初识Redis · C++客户端string
目录
前言:
string的API使用
set get:
expire:
NX XX:
mset,mget:
getrange setrange:
incr decr
前言:
在前文,我们已经学习了Redis的定制化客户端怎么来的,以及如何配置好Redis定制化客户端,并且简单学习了一下RESP,其实也就是了解了一下为什么Redis可以定制化客户端而已,那么,我们现在有了Redis定制化客户端的条件,我们自然就可以使用大佬们封装好的Redis的API了。
那么在本文呢,我们涉及到的是string,list和hash的多组API,因为我们是在命令行敲过的,所以学习起来也是非常快的了。
废话不多说,进入主题吧!
string的API使用
对于string的API使用,我们大致分为了 set get expire mset mget getrange setrange incr decr,大致就这么多命令,因为其他命令其实也大差不差,我们就使用过这些也都清楚了。
set get:

我们创建好了redis对象之后,啥也不管,直接set,我们可以看到它的参数还是挺多的,但是当我们一看,第一个参数是key,第二个参数是val,第三个参数是chrno的时间,这不就是存活时间吗,第四个参数是一些设置,比如NX,XX等。
这样一看是非常清楚的了。
但是我们发现set的参数是Stringview类型的,这个类型和string类型来说最大的区别就是这个类型是只读的,我们可以通过阅读源码简单了解:
begin() const noexcept{ return this->_M_str; }constexpr const_iteratorend() const noexcept{ return this->_M_str + this->_M_len; }constexpr const_iteratorcbegin() const noexcept{ return this->_M_str; }constexpr const_iteratorcend() const noexcept{ return this->_M_str + this->_M_len; }
这里是它经过重重封装后的源码,我们可以发现它的迭代器都是const类型,也就是不允许我们修改*this了,它即只读的。
因为是只读的,所以针对只读的这个操作做了很多优化,效率就比普通的std::string快了。当然了,在C++17中,标准库也提供了std::string_view,操作和string类似,只是包括了一些只读的方法。
那么我们既然set了,我们肯定要get,我们先看看get的返回值:
通过返回值和备注,我们看到了它的返回值是OptionalString,如果key是不存在的,那么会返回的就是通过nullop构造的OptionalString对象。那么OptionalString是什么呢~
实际上,它的出现是因为为了更好的处理key不存在的这个情况,在我们学习命令行的时候,我们如果使用get查看一个不存在的key,返回值是nil,也就是空的意思,那么如果它的返回值是string,我们如何表达nil?
如果返回空串,我们并不排除key对应的value就是空串,如果我们再复杂一点,返回一个string*,指向的是空就代表nil,可是这样又会引发出内存安全的问题。
所以,Redis官方给出的操作是给了一个类型:OptionalString,主要是为了处理nil的情况。
但是作为C++学习者我们不能不知道boost在C++14的时候就已经引入了optional<std::string>的概念了,后来在C++17的时候我们直接就包含optional的头文件就行了。
我们先来看一段正确的使用:
void test_1(Redis& redis)
{redis.flushall();redis.set("key","111");auto value = redis.get("key");if(value)std::cout << value.value() << std::endl;else std::cout << "值不存在" << std::endl;}
我们一共发现了三处左右较为陌生的点,一个是我们使用auto来接收,一个是我们用if来判断value,一个是我们使用的value.value()打印。
首先,我们最能够理解的点是,<<运算符并不支持OptionalString的打印,所以我们需要通过value()方法来返回string类型,其实我们也能通过*value来解决,它们的返回值都是string,*是重载了解引用操作符,.value()就是显示的调用了对应的成员函数。
if(value)std::cout << *value << std::endl;else std::cout << "值不存在" << std::endl;
其次,我们还能理解的是,如果我们get的是一个不存在的键值,那么OptionalString返回值就是类似于nil的结果,所以我们最好是做一个类型检查。
最后,我们使用auto来接收,其实我们使用optional<string>接收也不是不行,但是为了方便嘛,我们可以直接使用auto接收。不过就需要你包含对应的头文件了。
对应value()方法有一个特点就是如果key不存在,就会抛异常,像这样
从上面这个代码的例子,我们认识了OptionalString,stringView。
那么为了测试方便,我们最好在对Redis进行操作的时候flushall一下,以下是第一个测试的代码:
void test_1(Redis &redis)
{redis.flushall();redis.set("key", "111");auto value = redis.get("key");// std::optional<std::string> value = redis.get("key");// if(value)// std::cout << *value << std::endl;// else// std::cout << "值不存在" << std::endl;std::cout << value.value() << std::endl;
}
int main()
{Redis redis("tcp://127.0.0.1:6379");test_1(redis);return 0;
}
expire:
然后我们来测试以下超时时间,在set的构造函数中,我们直接加就可以了:
void test_2(Redis &redis)
{redis.flushall();redis.set("key","111",std::chrono::seconds(10));using namespace std::chrono_literals;redis.set("key1","222",10s);std::this_thread::sleep_for(3s);long long time = redis.ttl("key");std::cout << "剩余时间为:" << time << std::endl;}
这里的代码就比较简单了,第一个点是设置过期时间有两种方式,一种是使用命令空间chrono的seconds函数或者millonseconds函数,第二种方式是我们引入命名空间chrono_literals,这样我们就可以直接使用字面值常量了。
然后我们就正常根据ttl的返回值,来接收以下time就可以了:
至于为什么使用chrono等,因为C++不像py可以直接传10表示时间,C++没有内置时间单位,所以需要一个库专门用来表示时间的,就像上面的两个。
NX XX:
接着我们来测试NX和XX:

一般默认的是ALWAYS,XX对应的是EXIST,NX对应的是NOT_EXIST:
void test_3(Redis &redis)
{redis.flushall();redis.set("key", "111", 0s,sw::redis::UpdateType::NOT_EXIST);auto value = redis.get("key");if(value)std::cout << value.value() << std::endl;else std::cout << "not exist"<< std::endl;
}
mset,mget:
对于mset和mget来说就是今天的难点了算是,当然仅仅相对而言,它不过是需要我们引入迭代器的概念而已。
由于传键值对的时候,get和mget的键值对都是pair类型的,所以我们使用mget的时候,官方给我们提供了两个角度,一个是使用initailizer_list,一个是使用容器的迭代器。
void test_4(Redis &redis)
{redis.flushall();// redis.mset({"key1","111","key2","222"}); // errorredis.mset({std::make_pair("key","111"),std::make_pair("key1","222")});std::vector<std::pair<std::string, std::string>> vec{std::make_pair("key2","222"),std::make_pair("key3","333")};std::vector<std::pair<std::string, std::string>> vec2{{"key4","444"},{"key5","555"}};redis.mset(vec.begin(), vec.end());redis.mset(vec2.begin(), vec2.end());std::vector<std::string> result;auto iter = std::back_inserter(result); redis.mget({"key","key2","key4"},iter);for(auto ele:result){std::cout << ele << ' ';}std::cout << std::endl;
}

对于mset和mget来说,较为特殊,使用mset的时候,我们有两种方式,一种,我们可以直接使用initailizer_list初始化,就像构建key 和 key1的时候,我们也可以通过重载迭代器的方式,即我们先定义一个容器,可以是list可以是set可以是Vector,构造好了之后,mset直接传入两个的迭代器的就可以了。
然后是mget,使用mget的时候,我们可以看看参数:
它的第二个参数是back_insert_iterator,其实就是尾插迭代器,在STL中,迭代器分为了五种类型,分别是输入迭代器,输出迭代器,前向迭代器,双向迭代器和随机访问迭代器,其中对于back_inserter来说,它就是输出迭代器的一种,mget获取到value之后,就把输出给到这个迭代器对应的容器里面。
那么给的方式,就是看位置了,比如back_inserter对应的位置是尾,那么就相当于给这个容器一直尾插。
它们对应了不同的迭代器,比如back_insert_iterator,insert_iterator,但是我们一般不会直接构造出这几个对象,我们一般会走一些辅助的函数来构造,比如back_inserter。
getrange setrange:
这两个我们如果有了C++string函数的理解,那就非常简单了,无非是我们要确定位置,给个偏移量,然后给上对应的字符串就可以了。
void test_5(Redis &redis)
{redis.flushall();redis.set("key","abcdefghijk");redis.setrange("key",2,"11111111");std::string result = redis.getrange("key",2,-1);std::cout << result << std::endl;
}
incr decr
同理,非常简单,我们直接给代码:
void test_6(Redis &redis)
{redis.flushall();redis.set("key", "20");redis.incr("key");auto value = redis.get("key");if (value)std::cout << value.value() << std::endl;redis.decr("key");value = redis.get("key");if (value)std::cout << value.value() << std::endl;
}

也是非常简单了。
其实文本篇幅较多仅是因为第一次使用Redis对应的API,那么在之后介绍list和hash的时候节奏就会快了。
本文的难点是在mset和mget的时候,如何正确使用迭代器的问题,其他难度相对来说是比较低的。
感谢阅读!
相关文章:
初识Redis · C++客户端string
目录 前言: string的API使用 set get: expire: NX XX: mset,mget: getrange setrange: incr decr 前言: 在前文,我们已经学习了Redis的定制化客户端怎么来的,以及如何配置好Redis定制化客户端&…...
华硕原厂系统枪神9/9p超竟版-WIN11原装开箱出厂系统安装
华硕原厂系统枪神9/9p超竟版-WIN11-24H2-专业工作站版本安装可带F12-ASUSRecovery恢复功能 适用机型: G635LX、G635LW、G835LX、G835LW、G615LW、G615LP、G615LM、G615LH G815LW、G815LP、G815LM、G815LH、G635LR、G835LR、G615LR、G815LR 远程恢复安装ÿ…...
CF1016赛后总结
文章目录 前言T1:Ideal GeneratorT2:Expensive NumberT3:Simple RepetitionT4:Skibidi TableT5:Min Max MEXT6:Hackers and Neural NetworksT7:Shorten the Array 前言 由于最近在半期考试,更新稍微晚了一点,还望大家见谅 &#…...
QT聊天项目DAY06
1.从git上同步项目 编译测试,编译通过 Post请求测试 测试成功 2. email is 打印有问题,检查 解析结果是存储在jsonResult中的,修改 3. 客户端实现Post验证码请求 3.1 同步Qt客户端项目 检查QT版本,由于我在公司用的还是QT5.12.9…...
GNU,GDB,GCC,G++是什么?与其他编译器又有什么关系?
文章目录 前言1. GNU和他的工具1.1 gcc与g1.2 gdb 2.Windows的Mingw/MSVC3.LLVM的clang/clang4.Make/CMake 前言 在开始之前我们先放一段Hello World:hello.c #include <stdio.h>int main() {printf("Hello World");return 0; }然后就是一段老生常…...
【AI提示词】IT专家顾问
提示说明 IT 专家顾问是一位专注于IT行业的专家,拥有深厚的技术背景和广泛的知识储备。他们能够为企业、政府机构或其他组织提供技术支持、解决方案设计和战略规划。 提示词 # Role: IT 专家顾问## Profile - **语言**: 中文 - **描述**: IT 专家顾问是一位专注于…...
笔记整理五
STP生成树 stp生成树是用于解决二层环路问题的协议。 二层环路为有以下三种: 1.广播风暴 2.MAC地址的偏移(每一次循环,都会导致交换机来回刷新MAC地址表记录) 3.多帧复制 stp生成树:需要将原本的环型拓扑结构转换…...
Java中“this”关键字梳理详解
在Java中,this 是一个非常重要的关键字,它表示当前对象的引用。也就是说,当你在某个类的实例方法或构造器中时,this 指向调用该方法或创建的当前对象实例。以下将结合代码示例和具体场景,详细讲解 this 的用法及其作用…...
mybatis plus打印sql日志到指定目录
1、mybatis plus打印sql日志 参考文档:mybatis plus打印sql日志_mybatisplus日志打印-CSDN博客 2、修改 修改InfoLevelLogger Override public void debug(String s) {// 修改这里logger.info(s);log.debug(s); } 增加:log.debug(s); 修改logback.x…...
奥比中光tof相机开发学习笔记
针对奥比中光 tof相机,官方提供的资料如下ProcessOn Mindmap|思维导图 Orbbec SDK Python Wrapper基于Orbbec SDK进行设计封装,主要实现数据流接收,设备指令控制。下面就其开发适配进行如下总结: (1)系统配…...
Oracle游标和触发器
--1.游标 --什么是游标 --游标是数据库在内存中开辟的数据缓冲区 --作用:用于遍历查询返回之后的结果集(多条数据结果) --游标分类:隐式游标,显示游标,REF游标(动态游标) --游标的状…...
【面试向】点积与注意力机制,逐步编码理解自注意力机制
点积(dot product)两个向量点积的数学公式点积(dot product)与 Attention 注意力机制(Attention)注意力机制的核心思想注意力机制中的缩放点积自注意力机制中,谁注意谁? 逐步编码理解…...
00.IDEA 插件推荐清单(2025)
IDEA 插件推荐清单 精选高效开发必备插件,提升 Java 开发体验与效率。 参考来源:十六款好用的 IDEA 插件,强烈推荐!!!不容错过 代码开发助手类 插件名称功能简介推荐指数CodeGeeX智能代码补全、代码生成、…...
一个 CTO 的深度思考
今天和一些同事聊了一会,以下是我的观点 我的观点,成年人只能筛选,不能培养在组织中,应该永远向有结果的人看齐。不能当他站出来讲话的时候,大家还要讨论讨论,他虽然拿到结果了,但是他就是有一…...
MVC/MVVM 高级应用的深度解析
状态共享与同步 跨组件状态管理策略 状态变更的传播机制优化 状态快照与时间旅行调试 状态持久化 本地存储策略 状态序列化与反序列化 与服务端状态同步 数据绑定进阶 双向绑定优化 脏检查机制优化 基于Proxy/Object.defineProperty的实现差异 批量更新策略 自定义…...
SQL通用语法和注释,SQL语句分类(DDL,DML,DQL,DCL)及案例
目录 SQL通用语法和注释 SQL语句分类(DDL,DML,DQL,DCL,TPL,CCL) DDL(数据定义语言) 数据库操作 查询(SHOW、SELECT) 创建(CREAT…...
当算力遇上马拉松:一场科技与肉身的极限碰撞
目录 一、从"肉身苦修"到"科技修仙" 二、马拉松的"新大陆战争" 三、肉身会被算法"优化"吗? 马拉松的下一站是"人机共生"时代 当AI能预测你的马拉松成绩,算法能规划最佳补给方案,智能装备让训练效率翻倍——你还会用传…...
AUTOSAR图解==>AUTOSAR_SWS_KeyManager
AUTOSAR KeyManager详细分析 AUTOSAR 4.4.0 版本密钥与证书管理模块技术分析 目录 1. 概述2. KeyManager架构 2.1 KeyManager在AUTOSAR架构中的位置2.2 架构说明 3. KeyManager模块结构 3.1 模块组件详解3.2 配置项说明 4. KeyManager证书验证流程 4.1 证书验证流程分析 5. Ke…...
用usb网卡 虚拟机无法开到全双工的解决办法
今天突发奇想 给unraid宿主机插了两个一摸一样的usb网卡 2.5g的 直通给不同的虚拟机 这里unraid需要安装"USB Manager" 请给unraid自备环境 直通的时候 第一次还没生效 看不到网卡 我又在unraid的管理界面 顶部可以看到多出来一个 "usb"页面 打开可…...
5. 话题通信 ---- 发布方和订阅方python文件编写
本节对应赵虚左ROS书籍的2.1.3 以10hz,发布消息和消息的订阅 1)在功能包下新建scripts文件夹,在scripts文件夹下新建python文件,写入 #! /usr/bin/env pythonfrom std_msgs.msg import String import rospyif __name__ "__main__":rospy.i…...
Jsp技术入门指南【七】JSP动作讲解
Jsp技术入门指南【七】JSP动作讲解 前言一、什么是JSP动作?二、核心JSP动作详解1. jsp:include:动态包含其他页面与<% include %>的区别 2. jsp:forward:请求转发到另一个页面3. jsp:param:为动作传递参数4. jsp:useBean&am…...
10软件测试需求分析案例-查询学习信息
用户登录系统后,进入查询学生信息界面,输入查询字段值,点击查询按钮后,展示查询到的学生信息,可以重新输入字段值进行查询。 查询学生信息属于学生信息管理的子菜单,可以根据学号、姓名、性别查询。老师登录…...
基于尚硅谷FreeRTOS视频笔记——6—滴答时钟—上下文切换
FreeRTOS滴答 FreeRTOS需要有一个时钟参照,并且这个时钟不会被轻易打断,所以最好选择systick 为什么需要时间参照 就是在高优先级任务进入阻塞态后,也可以理解为进入delay()函数后,需要有一个时间参照&…...
Lambda 表达式的语法结构
Java 中的 Lambda 表达式的基本结构如下: (参数列表) -> { 方法体 } ✅ 语法形式举例(从简单到复杂) 形式示例说明无参数() -> System.out.println("Hi")没有参数,执行一个语句一个参数x -> x *…...
SEOFOMO调研揭示:2025年电商SEO如何利用人工智能
随着人工智能(AI)技术在数字营销领域的深入应用,电子商务(电商)搜索引擎优化(SEO)的实践正在发生深刻变革。2025年4月17日,Aleyda Solis 的 SEOFOMO 发布了一项针对电商业主和 SEO 从…...
linux下C++性能调优常用的工具
性能优化的常见流程 发现问题--->定位问题--->解决问题--->验证问题 发现问题的常见工具 1.定位内存问题 top指令,发现占用内存多的线程 asan 发现内存问题。 2.定位cpu问题 top指令,发现占用cpu多的进程,线程 一般对内存和…...
Docker安装 (centos)
1.安装依赖包: sudo yum install -y yum-utils device-mapper-persistent-data lvm2 2.删除已有的 Docker 仓库文件(如果有): sudo rm -f /etc/yum.repos.d/docker-ce.repo 3.添加阿里云的 Docker 仓库: sudo yum…...
MCP服务,阿里云百炼,Cline,mysql-mcp-server,MCP通信原理
简介 MCP(Model Context Protocol),模型上下文协议,是一种开放标准,用于将AI模型与外部数据源和工具建立安全的双向连接,它就像AI领域的USB-C接口,为AI模型提供了一种标准化方式来连接不同的数…...
一个项目中多个Composer的使用方法
composer是依赖管理工具。 有时我们会在一个项目中使用到多个composer,且每个版本不同。 前提:例如项目xyz根目录vendor中存在阿里云的对应代码。我现在需要再composer腾讯云短信发送的SDK。 1、随便找个位置新建文件夹,存储腾讯云短信发送…...
MCP 应用案例-网络设备批量管理
案例背景 需求痛点 企业需管理数百台跨地域网络设备(交换机/路由器),传统方式存在: 人工SSH登录效率低脚本维护成本高(不同厂商CLI语法差异)状态监控依赖独立监控系统 解决方案 通过MCP协议构建智能网络…...
