Redis 可以通过使用子串操作和二进制位操作,配合 WATCH 、MULTI 和 EXEC 命令(后面会初步介绍,以后将深入讲解),构建任何想要的数据结构。
列表 P42 一些常用的列表命令 P42 命令 格式 描述RPUSH RPUSH key value [value ...] 依次将一个或多个 value 从列表右端插入
LPUSH LPUSH key value [value ...] 依次将一个或多个 value 从列表左端插入
RPOP RPOP key 移除并返回列表最右端的元素
LPOP LPOP key 移除并返回列表最左端的元素
LINDEX LINDEX key offset 返回列表左端开始偏移量为 offset 的元素
LRANGE LRANGE key start end 返回列表左端开始 [start, end] 范围内的所有元素
LTRIM LTRIM key start end 移除列表左端开始 [start, end] 范围外的所有元素
相关演示代码如下:
// 执行列表类型相关操作 func executeListOperation(conn redis.Conn) { // 删除原有值 handleResult(redis.Int(conn.Do("DEL", "list"))) // 右端插入一次插入 a, b, c,返回当前列表长度 -> 3,列表变为 -> a b c handleResult(redis.Int(conn.Do("RPUSH", "list", "a", "b", "c"))) // 左端插入一次插入 d, e, f,返回当前列表长度 -> 6,列表变为 -> f e d a b c handleResult(redis.Int(conn.Do("LPUSH", "list", "d", "e", "f"))) // 弹出并返回列表最右端的值,返回 -> c,列表变为 -> f e d a b handleResult(redis.String(conn.Do("RPOP", "list"))) // 弹出并返回列表最左端的值,返回 -> f,列表变为 -> e d a b handleResult(redis.String(conn.Do("LPOP", "list"))) // 返回左端开始下标偏移量为 offset 的值,返回 -> d handleResult(redis.String(conn.Do("LINDEX", "list", 1))) // 移除列表左端开始 [1, 2] 范围外的所有元素,列表变为 -> d a handleResult(redis.String(conn.Do("LTRIM", "list", 1, 2))) }利用 LTRIM 命令可以原子地弹出多个元素。 P43
阻塞式的列表弹出命令以及在列表之间移动元素的命令 P43 命令 格式 描述BLPOP BLPOP key [key ...] timeout 从第一个非空列表中弹出最左端的元素,或者在 timeout 秒内阻塞并等待可弹出的元素出现,返回被弹出的列表名及元素, timeout 为 0 表示无限等待
BRPOP BRPOP key [key ...] timeout 从第一个非空列表中弹出最右端的元素,或者在 timeout 秒内阻塞并等待可弹出的元素出现,返回被弹出的列表名及元素, timeout 为 0 表示无限等待
RPOPLPUSH RPOPLPUSH source destination 从 source 列表中弹出最右端的元素,然后将这个元素退出 destination 列表的最左端,并返回这个元素
BRPOPLPUSH BRPOPLPUSH source destination timeout 从 source 列表中弹出最右端的元素,然后将这个元素退出 destination 列表的最左端,并返回这个元素;如果 source 列表为空,则在 timeout 秒内阻塞并等待可弹出元素出现
相关演示代码如下:
// 执行列表类型阻塞相关操作 func executeListBlockOperation(conn redis.Conn) { // 删除原有值 handleResult(redis.Int(conn.Do("DEL", "source", "destination"))) // 从第一个非空列表中弹出并返回列表最左端的值,最多等待 1秒,输出 -> ERROR: redigo: nil returned handleResult(redis.Strings(conn.Do("BLPOP", "source", "destination", 1))) // 初始化 handleResult(redis.Int(conn.Do("RPUSH", "source", "a", "b", "c"))) handleResult(redis.Int(conn.Do("RPUSH", "destination", "d", "e", "f"))) // 从第一个非空列表中弹出并返回列表最左端的值,无限等待,返回 -> a,source 变为 -> b c,destination 变为 -> d e f handleResult(redis.Strings(conn.Do("BLPOP", "source", "destination", 0))) // 从第一个非空列表中弹出并返回列表最右端的值,无限等待,返回 -> f,source 变为 -> b c,destination 变为 -> d e handleResult(redis.Strings(conn.Do("BRPOP", "destination", "source", 0))) // 从 source 弹出最右端元素,然后推入到 destination 最左端,并返回这个元素 // 返回 -> c,source 变为 -> b,destination 变为 -> c d e handleResult(redis.String(conn.Do("RPOPLPUSH", "source", "destination"))) // 从 source 弹出最右端元素,然后推入到 destination 最左端,并返回这个元素,无限等待 // 返回 -> b,source 变为 -> <nil>,destination 变为 -> b c d e handleResult(redis.String(conn.Do("BRPOPLPUSH", "source", "destination", 0))) // 从 source 弹出最右端元素,然后推入到 destination 最左端,并返回这个元素,最多等待 1秒 // 输出 -> ERROR: redigo: nil returned,source 变为 -> <nil>,destination 变为 -> b c d e handleResult(redis.String(conn.Do("BRPOPLPUSH", "source", "destination", 1))) }