[Redis#12] 常用类型接口学习 | string | list

news2024/12/26 20:09:32

目录

0.准备

1.string

get | set

set_with_timeout_test.cpp

set_nx_xx_test.cpp

mset_test.cpp

mget_test.cpp

getrange_setrange_test.cpp

incr_decr_test.cpp

2.list

lpush_lrange_test.cpp

rpush_test.cpp

lpop_rpop_test.cpp

blpop_test.cpp

llen_test.cpp


0.准备

我们可以先定义了三个模板函数,用于打印不同类型的容器内容。每个函数都接受一个容器作为参数,并根据容器内元素的类型以不同的方式打印它们。

1.printContainer 函数

template<typename T>
inline void printContainer(const T& container) {
    for (const auto& elem : container) {
        std::cout << elem << std::endl;
    }
}
  • 该函数适用于任何包含可以直接输出到 std::cout 的元素的容器(如 int, double, std::string 等)。
  • 它遍历容器中的每个元素,并使用 std::cout 打印每个元素。

2.printContainerPair 函数

template<typename T>
inline void printContainerPair(const T& container) {
    for (auto& elem : container) {
        // 此处预期 elem 是一个 std::pair
        std::cout << elem.first << ": " << elem.second << std::endl;
    }
}
  • 这个函数专为存储 std::pair 类型元素的容器设计,比如 std::mapstd::unordered_map 中的键值对。
  • 对于每个元素,它假设 elem 是一个 std::pair,并打印出 pairfirstsecond 成员。

3.printContainerOptional 函数

template<typename T>
inline void printContainerOptional(const T& container) {
    for (const auto& elem : container) {
        // 此处预期 elem 是一个 optional 类型的元素, 打印之前, 先判定一下, 看是否有效
        if (elem) {
            std::cout << elem.value() << std::endl;
        } else {
            std::cout << "元素无效" << std::endl;
        }
    }
}
  • 此函数针对包含 std::optional 类型元素的容器。
  • 在打印之前,它会检查每个 optional 元素是否有效(即是否包含值)。如果有效,则调用 value() 方法获取其值并打印;如果无效,则打印“元素无效”。

示例

#include <vector>
#include <map>
#include <optional>
#include <iostream>

// 假设上面的函数已经定义好了

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::map<std::string, int> nameAge = {{"Alice", 30}, {"Bob", 25}};
    std::vector<std::optional<int>> optionals = {10, {}, 20, {}};

    printContainer(numbers);
    printContainerPair(nameAge);
    printContainerOptional(optionals);

    return 0;
}

运行:


1.string

redis.get()返回的是一个optional类型

  • optional类型在C++14中,正式纳入标准库
  • 因为redis.get()会返回nil无效值,用std::string不方便表现nil,而std::string*虽然可以用nullptr表示无效,但是返回指针又设计内存管理问题
  • 所以综上,此处使用optional表示"非法值"/“无效值”
get | set
// test1.cpp
#include <iostream>
#include <sw/redis++/redis++.h>
#include "util.hpp"

using namespace std;
using sw::redis::Redis;

void test1(Redis& redis) {
    cout << "get 和 set" << endl;
    redis.flushall();

    redis.set("key", "111");//类命令
    auto value = redis.get("key");//接收命令 返回值
    if (value) {
        cout << "value: " << value.value() << endl;
    }

    redis.set("key", "222");
    value = redis.get("key");
    if (value) {
        cout << "value: " << value.value() << endl;
    }
}

运行:

⭕注意:

1.redis.flushall(); 在 test 开始

  • 作用:清空数据库,避免之前残留的数据干扰

2.get return 的 value 取值采取:value.value()

set_with_timeout_test.cpp

这个文件包含了 test2 函数,用于测试带有超时时间的 set 命令。

// set_with_timeout_test.cpp
#include <iostream>
#include <chrono>
#include <thread>
#include <sw/redis++/redis++.h>

using namespace std;
using namespace std::chrono_literals;
using sw::redis::Redis;

void test2(Redis& redis) {
    cout << "set 带有超时时间" << endl;
    redis.flushall();

    redis.set("key", "111", 10s);

    this_thread::sleep_for(3s);

    long long time = redis.ttl("key");
    cout << "time: " << time << endl;
}

set_nx_xx_test.cpp

这个文件包含了 test3 函数,用于测试 set 命令的 NXXX 选项。

// set_nx_xx_test.cpp
#include <iostream>
#include <sw/redis++/redis++.h>

using namespace std;
using sw::redis::Redis;
using sw::redis::UpdateType;

void test3(Redis& redis) {
    cout << "set NX 和 XX" << endl;
    redis.flushall();

    redis.set("key", "111");
 // set 的重载版本中, 没有单独提供 NX 和 XX 的版本, 必须搭配过期时间的版本来使用. 
    redis.set("key", "222", 0s, UpdateType::EXIST);

    auto value = redis.get("key");
    if (value) {
        cout << "value: " << value.value() << endl;
    } else {
        cout << "key 不存在!" << endl;
    }
}

mset_test.cpp

这个文件包含了 test4 函数,用于测试 mset 命令。

注意:

  • 可以把多个键值对提前组织到容器 vector<pair<string, string>> 中. 以迭代器的形式告诉 mset
// mset_test.cpp
#include <iostream>
#include <vector>
#include <sw/redis++/redis++.h>

using namespace std;
using sw::redis::Redis;

void test4(Redis& redis) {
    cout << "mset" << endl;

    redis.flushall();

// 第一种写法, 使用初始化列表描述多个键值对
    // redis.mset({ std::make_pair("key1", "111"), std::make_pair("key2", "222"), std::make_pair("key3", "333") });

    // 第二种写法, 可以把多个键值对提前组织到容器中. 以迭代器的形式告诉 mset
    
    vector<pair<string, string>> keys = {
        {"key1", "111"},
        {"key2", "222"},
        {"key3", "333"}
    };
    redis.mset(keys.begin(), keys.end());

    auto value = redis.get("key1");
    if (value) {
        cout << "value: " << value.value() << endl;
    }

    value = redis.get("key2");
    if (value) {
        cout << "value: " << value.value() << endl;
    }

    value = redis.get("key3");
    if (value) {
        cout << "value: " << value.value() << endl;
    }
}

mget_test.cpp

这个文件包含了 test5 函数,用于测试 mget 命令。

// mget_test.cpp
#include <iostream>
#include <vector>
#include <sw/redis++/redis++.h>
#include "util.hpp"

using namespace std;
using sw::redis::Redis;
using sw::redis::OptionalString;

void test5(Redis& redis) {
    cout << "mget" << endl;
    redis.flushall();

    vector<pair<string, string>> keys = {
        {"key1", "111"},
        {"key2", "222"},
        {"key3", "333"}
    };
    redis.mset(keys.begin(), keys.end());

    vector<OptionalString> result;
    auto it = back_inserter(result);
    redis.mget({"key1", "key2", "key3", "key4"}, it);

    printContainerOptional(result);
}
getrange_setrange_test.cpp

这个文件包含了 test6 函数,用于测试 getrange (return string) 和 setrange 命令。

// getrange_setrange_test.cpp
#include <iostream>
#include <string>
#include <sw/redis++/redis++.h>

using namespace std;
using sw::redis::Redis;

void test6(Redis& redis) {
    cout << "getrange 和 setrange" << endl;
    redis.flushall();

    redis.set("key", "abcdefghijk");

    string result = redis.getrange("key", 2, 5);
    cout << "result: " << result << endl;

    redis.setrange("key", 2, "xyz");

    auto value = redis.get("key");
    cout << "value: " << value.value() << endl;
}
incr_decr_test.cpp

这个文件包含了 test7 函数,用于测试 incrdecr 命令。

// incr_decr_test.cpp
#include <iostream>
#include <sw/redis++/redis++.h>

using namespace std;
using sw::redis::Redis;

void test7(Redis& redis) {
    cout << "incr 和 decr" << endl;
    redis.flushall();

    redis.set("key", "100");
    //对比关注 如下两种返回结果
    
    //返回结果1:long long
    long long result = redis.incr("key");
    cout << "result: " << result << endl;

    //返回结果2:对象
    auto value = redis.get("key");
    cout << "value: " << value.value() << endl;

    result = redis.decr("key");
    cout << "result: " << result << endl;

    value = redis.get("key");
    cout << "value: " << value.value() << endl;
}

运行:


2.list

lpush_lrange_test.cpp

这个文件包含了 test1 函数,用于测试 lpushlrange 命令。

// lpush_lrange_test.cpp
#include <iostream>
#include <vector>
#include <string>
#include <sw/redis++/redis++.h>
#include "util.hpp"

using namespace std;
using sw::redis::Redis;

void test1(Redis& redis) {
    cout << "lpush 和 lrange" << endl;
    redis.flushall();

    // 插入单个元素
    redis.lpush("key", "111");

    // 插入一组元素, 基于初始化列表
    redis.lpush("key", {"222", "333", "444"});

    // 插入一组元素, 基于迭代器
    vector<string> values = {"555", "666", "777"};
    redis.lpush("key", values.begin(), values.end());

    // lrange 获取到列表中的元素
    vector<string> results;//容器
    auto it = back_inserter(results);//创建插入迭代器,用于将元素添加到容器的末尾
    redis.lrange("key", 0, -1, it);

    printContainer(results);
}

关于这个地方迭代器的使用,详细可以看前面两篇博文

  • [Redis#11] cpp-redis | 通用命令 | optional | 插入迭代器
  • STL 源码剖析 note(这个专栏 还在完善中 后续应该会发)

运行

rpush_test.cpp

这个文件包含了 test2 函数,用于测试 rpush 命令。

// rpush_test.cpp
#include <iostream>
#include <vector>
#include <string>
#include <sw/redis++/redis++.h>
#include "util.hpp"

using namespace std;
using sw::redis::Redis;

void test2(Redis& redis) {
    cout << "rpush" << endl;
    redis.flushall();

    // 插入单个元素
    redis.rpush("key", "111");

    // 插入多个元素, 基于初始化列表
    redis.rpush("key", {"222", "333", "444"});

    // 插入多个元素, 基于容器
    vector<string> values = {"555", "666", "777"};
    redis.rpush("key", values.begin(), values.end());

    // 使用 lrange 获取元素
    vector<string> results;
    auto it = back_inserter(results);
    redis.lrange("key", 0, -1, it);

    printContainer(results);
}

lpop_rpop_test.cpp

这个文件包含了 test3 函数,用于测试 lpoprpop 命令。

// lpop_rpop_test.cpp
#include <iostream>
#include <optional>
#include <sw/redis++/redis++.h>

using namespace std;
using sw::redis::Redis;

void test3(Redis& redis) {
    cout << "lpop 和 rpop" << endl;
    redis.flushall();

    // 构造一个 list
    redis.rpush("key", {"1", "2", "3", "4"});

    auto result = redis.lpop("key");
    if (result) {
        cout << "lpop: " << result.value() << endl;
    }

    result = redis.rpop("key");
    if (result) {
        cout << "rpop: " << result.value() << endl;
    }
}

如果删除成功了,就打印 .value()

blpop_test.cpp

这个文件包含了 test4 函数,用于测试 blpop 命令。

  • TIPS:对于std::optional类型来说,可以直接使用->访问optional内部包含的元素的成员
// blpop_test.cpp
#include <iostream>
#include <chrono>
#include <sw/redis++/redis++.h>

using namespace std;
using namespace std::chrono_literals;
using sw::redis::Redis;

void test4(Redis& redis) {
    using namespace std::chrono_literals;
    cout << "blpop" << endl;
    redis.flushall();

    auto result = redis.blpop({"key", "key2", "key3"}, 10s);
    if (result) {
        cout << "key:" << result->first << endl;
        cout << "elem:" << result->second << endl;
    } else {
        cout << "result 无效!" << endl;
    }
}
llen_test.cpp

这个文件包含了 test5 函数,用于测试 llen 命令。

return long long

// llen_test.cpp
#include <iostream>
#include <sw/redis++/redis++.h>

using namespace std;
using sw::redis::Redis;

void test5(Redis& redis) {
    cout << "llen" << endl;
    redis.flushall();

    redis.lpush("key", {"111", "222", "333", "444"});
    long long len = redis.llen("key");
    cout << "len: " << len << endl;
}


对于 接口的返回值,我们可以在 上一篇文章中提到的 文档中查找

为了加深印象 ,和有充裕的时间学习,博主就都测试了一下,下一篇文章 应该会把剩余的常见三种类型测试完,然后 接口调用体会的 汇总,之后要是 用到了,看下一篇文章的总结就好啦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2252086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络安全之IP伪造

眼下非常多站点的涉及存在一些安全漏洞&#xff0c;黑客easy使用ip伪造、session劫持、xss攻击、session注入等手段危害站点安全。在纪录片《互联网之子》&#xff08;建议搞IT的都要看下&#xff09;中。亚伦斯沃茨&#xff08;真实人物&#xff0c;神一般的存在&#xff09;涉…

Spring Web开发(请求)获取JOSN对象| 获取数据(Header)

大家好&#xff0c;我叫小帅今天我们来继续Spring Boot的内容。 文章目录 1. 获取JSON对象2. 获取URL中参数PathVariable3.上传⽂件RequestPart3. 获取Cookie/Session3.1 获取和设置Cookie3.1.1传统获取Cookie3.1.2简洁获取Cookie 3. 2 获取和存储Session3.2.1获取Session&…

(SAST检测规则-1)Android - 权限管理漏洞

所属分类&#xff1a;Android - 权限管理漏洞缺陷详解&#xff1a;应用未正确实施最小权限原则或滥用已声明的权限可能导致敏感信息泄露。例如&#xff0c;恶意代码利用已授予的权限绕过用户授权&#xff0c;访问通讯录、位置、短信等敏感资源。部分开发者还可能滥用权限以执行…

EC2还原快照

EC2还原快照 AWS EC2 磁盘快照 是您 Amazon Elastic Block Store (EBS) 卷在特定时间点的增量备份。您可以使用快照创建 EBS 卷的副本&#xff0c;以便在出现故障时恢复数据或将数据迁移到其他区域。 创建磁盘快照 找到ec2实例挂载的磁盘&#xff0c;直接选择创建快照 等待创建…

oracle RAC各版本集群总结和常用命令汇总

oracle RAC学习 RAC介绍 RAC&#xff1a;高可用集群&#xff0c;负载均衡集群&#xff0c;高性能计算集群 RAC是⼀种⾼可⽤&#xff0c;⾼性能&#xff0c;负载均衡的share-everything的集群 8i:内存融合雏形 内存融合雏形&#xff08;Oracle Parallel Server&#xff09;…

【聚类】K-Means 聚类(无监督)及K-Means ++

1. 原理 2. 算法步骤 3. 目标函数 4. 优缺点 import torch import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.decomposition import PCA import torch.nn as nn# 数据准备 # 生成数据&#xff1a;100 个张量&#xff0c…

智慧银行反欺诈大数据管控平台方案(一)

智慧银行反欺诈大数据管控平台建设方案的核心在于通过整合先进的大数据技术和深度学习算法&#xff0c;打造一个全面、智能且实时的反欺诈系统&#xff0c;以有效识别、预防和应对各类金融欺诈行为。该方案涵盖数据采集、存储、处理和分析的全流程&#xff0c;利用多元化的数据…

搭建业务的性能优化指南

这是一篇搭建业务优化的心路历程&#xff0c;也是写给搭建业务的性能优化指南。 前言 直到今天&#xff0c;淘内的页面大多都迁移到了 SSR&#xff0c;从我们终端平台 - 搭建研发团队的视角看&#xff0c;业务大致可以分为两类 —— 搭建派 和 源码派。 这两者互不冲突&#xf…

【Db First】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…

搭建私有云存储

1、安装LNMP环境 yum install nginx -y yum install -y nginx mariadb-server php php-fpm php-mysqlnd systemctl restart nginx.service --- 启动Nginx systemctl start mariadb.service ---启动数据库 mysql -e create database lxdb character set utf8 ---创建数据库 my…

YOLO 标注工具 AutoLabel 支持 win mac linux

常见的标注工具&#xff0c;功能基础操作繁琐&#xff0c;无复制粘贴&#xff0c;标签无法排序修改&#xff0c;UI不美观&#xff0c;bug修正不及时&#xff0c;没有集成识别、训练、模型导出… 怎么办呢&#xff1f;AutoLabel它来了 Quick Start 一图胜千言 图像标注 支持YOL…

qt QGraphicsPolygonItem详解

1、概述 QGraphicsPolygonItem是Qt框架中QGraphicsItem的一个子类&#xff0c;它提供了一个可以添加到QGraphicsScene中的多边形项。通过QGraphicsPolygonItem&#xff0c;你可以定义和显示一个多边形&#xff0c;包括其填充颜色、边框样式等属性。QGraphicsPolygonItem支持各…

Linux网络_网络协议_网络传输_网络字节序

一.协议 1.概念 协议&#xff08;Protocol&#xff09; 是一组规则和约定&#xff0c;用于定义计算机网络中不同设备之间如何进行通信和数据交换。协议规定了数据的格式、传输方式、传输顺序等详细规则&#xff0c;确保不同设备和系统能够有效地互联互通。 在网络通信中&#…

MySQL查看日志

目录 1. 日志 1.1 错误日志 1.2 二进制日志 1.2.1 介绍 1.2.2 格式 1.2.3 查看 1.2.4 删除 1.3 查询日志 1.4 慢查询日志 1. 日志 1.1 错误日志 错误日志是 MySQL 中最重要的日志之一&#xff0c;它记录了当 mysqld 启动和停止时&#xff0c;以及服务器在运行过…

【深度学习】四大图像分类网络之AlexNet

AlexNet是由Alex Krizhevsky、Ilya Sutskever&#xff08;均为Hinton的学生&#xff09;和Geoffrey Hinton&#xff08;被誉为”人工智能教父“&#xff0c;首先将反向传播用于多层神经网络&#xff09;在2012年ImageNet图像分类竞赛中提出的一种经典的卷积神经网络。AlexNet在…

MySQL数据库做题笔记

题目链接https://leetcode.cn/problems/invalid-tweets-ii/description/https://leetcode.cn/problems/invalid-tweets-ii/description/ # Write your MySQL query statement below SELECT tweet_id FROM Tweets where LENGTH(content)>140 OR (length(content)-length(rep…

ansible使用说明

将安装包拷贝到主控端主机 在主控端主机安装ansible&#xff0c;sh setup.sh 确认安装成功后&#xff0c;编辑hosts文件&#xff08;按步骤逐个添加主机组&#xff0c;不要一开始全部配置好&#xff09; [site-init]下的主机列表为被控制的主机&#xff08;按照当前ai建模方案…

EDA软件研发的DevOps平台

1&#xff1a;什么是DevOps DevOps是十几年前&#xff0c;在互联网比较火的词&#xff0c;实际上就是ci/cd平台的另外一种说法&#xff0c;核心是说打破研发&#xff0c;测试&#xff0c;运维的边界&#xff0c;能够将整个产品开发的流程快速循环起来&#xff0c;随时可发版&a…

Linux命令进阶·如何切换root以及回退、sudo命令、用户/用户组管理,以及解决创建用户不显示问题和Ubuntu不显示用户名只显示“$“符号问题

目录 1. root用户&#xff08;超级管理员&#xff09; 1.1 用于账户切换的系统命令——su 1.2 退回上一个用户命令——exit 1.3 普通命令临时授权root身份执行——sudo 1.3.1 为普通用户配置sudo认证 2. 用户/用户组管理 2.1 用户组管理 2.2 用户管理 2.2.1 …

网络安全-AAA介绍与配置

前言 AAA是Authentication&#xff08;认证&#xff09;、Authorization&#xff08;授权&#xff09;和Accounting&#xff08;计费&#xff09;的简称&#xff0c;它提供了认证、授权、计费三种安全功能。AAA可以通过多种协议来实现&#xff0c;目前华为设备支持基于RADIUS&a…