pub struct RedisClient { /* private fields */ }Expand description
Redis 客户端
提供 Redis 数据库操作的统一接口,支持连接池管理
Implementations§
Source§impl RedisClient
impl RedisClient
Sourcepub async fn connect(url: impl Into<String>) -> Result<Self>
pub async fn connect(url: impl Into<String>) -> Result<Self>
连接到 Redis 服务器
§参数
url: Redis 连接 URL,格式为redis://host:port或redis://host:port/db
§返回
Ok(RedisClient): 连接成功Err(DbError): 连接失败
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
Ok(())
}Sourcepub async fn connect_with_config(
url: impl Into<String>,
config: RedisConfig,
) -> Result<Self>
pub async fn connect_with_config( url: impl Into<String>, config: RedisConfig, ) -> Result<Self>
使用自定义配置连接到 Redis 服务器
§参数
url: Redis 连接 URLconfig: Redis 配置
§返回
Ok(RedisClient): 连接成功Err(DbError): 连接失败
§示例
use yang_db::{RedisClient, RedisConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = RedisConfig::new(20, 10, 15, true);
let client = RedisClient::connect_with_config("redis://127.0.0.1:6379", config).await?;
Ok(())
}Sourcepub fn pipeline(&self) -> RedisPipeline
pub fn pipeline(&self) -> RedisPipeline
创建 Pipeline 批量操作
Pipeline 允许将多个命令打包发送到 Redis 服务器,减少网络往返次数,提高性能。
§返回
新的 Pipeline 实例
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
let mut pipeline = client.pipeline();
pipeline.set("key1", "value1")
.set("key2", "value2")
.get("key1")
.incr("counter");
let results = pipeline.execute().await?;
println!("Pipeline 执行结果: {:?}", results);
Ok(())
}Sourcepub fn transaction(&self) -> RedisTransaction
pub fn transaction(&self) -> RedisTransaction
创建 Redis 事务
使用 WATCH/MULTI/EXEC 机制实现乐观锁事务。事务会自动处理 WATCH 冲突并重试。
§返回
新的事务实例
§示例:基础事务
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
let mut tx = client.transaction();
tx.set("key1", "value1")
.set("key2", "value2")
.incr("counter");
let results: (String, String, i64) = tx.exec().await?;
println!("事务执行结果: {:?}", results);
Ok(())
}§示例:乐观锁实现余额扣减
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
// 初始化余额
client.set("balance", "1000").await?;
// 读取当前余额
let balance_str = client.get("balance").await?.unwrap();
let balance: i64 = balance_str.parse().unwrap();
// 使用事务扣减余额
if balance >= 100 {
let mut tx = client.transaction();
tx.watch(&["balance".to_string()]);
tx.set("balance", (balance - 100).to_string());
let result: (String,) = tx.exec().await?;
println!("余额扣减成功: {:?}", result);
}
Ok(())
}Sourcepub async fn execute(&self, cmd: &Cmd) -> Result<RedisValue>
pub async fn execute(&self, cmd: &Cmd) -> Result<RedisValue>
执行 Redis 命令
§参数
cmd: Redis 命令
§返回
Ok(RedisValue): 命令执行成功Err(DbError): 命令执行失败
§示例
use yang_db::RedisClient;
use redis::cmd;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
let mut cmd = cmd("SET");
cmd.arg("key").arg("value");
let result = client.execute(&cmd).await?;
Ok(())
}Sourcepub async fn setex(
&self,
key: impl Into<String>,
seconds: i64,
value: impl Into<String>,
) -> Result<()>
pub async fn setex( &self, key: impl Into<String>, seconds: i64, value: impl Into<String>, ) -> Result<()>
Sourcepub async fn setnx(
&self,
key: impl Into<String>,
value: impl Into<String>,
) -> Result<bool>
pub async fn setnx( &self, key: impl Into<String>, value: impl Into<String>, ) -> Result<bool>
Sourcepub async fn getset(
&self,
key: impl Into<String>,
value: impl Into<String>,
) -> Result<Option<String>>
pub async fn getset( &self, key: impl Into<String>, value: impl Into<String>, ) -> Result<Option<String>>
Sourcepub async fn append(
&self,
key: impl Into<String>,
value: impl Into<String>,
) -> Result<i64>
pub async fn append( &self, key: impl Into<String>, value: impl Into<String>, ) -> Result<i64>
Sourcepub async fn getrange(
&self,
key: impl Into<String>,
start: i64,
end: i64,
) -> Result<String>
pub async fn getrange( &self, key: impl Into<String>, start: i64, end: i64, ) -> Result<String>
GETRANGE - 获取字符串的子串
§参数
key: 键start: 起始偏移量(0 表示第一个字符,-1 表示最后一个字符)end: 结束偏移量(包含)
§返回
Ok(String): 子串内容
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
// 假设 key "mykey" 的值是 "Hello World"
client.set("mykey", "Hello World").await?;
let substr = client.getrange("mykey", 0, 4).await?; // "Hello"
let substr2 = client.getrange("mykey", -5, -1).await?; // "World"
Ok(())
}Sourcepub async fn setrange(
&self,
key: impl Into<String>,
offset: i64,
value: impl Into<String>,
) -> Result<i64>
pub async fn setrange( &self, key: impl Into<String>, offset: i64, value: impl Into<String>, ) -> Result<i64>
SETRANGE - 从指定偏移量开始替换字符串内容
§参数
key: 键offset: 起始偏移量value: 要设置的值
§返回
Ok(i64): 修改后字符串的长度
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
client.set("mykey", "Hello World").await?;
let len = client.setrange("mykey", 6, "Redis").await?; // "Hello Redis"
Ok(())
}Sourcepub async fn incrbyfloat(
&self,
key: impl Into<String>,
increment: f64,
) -> Result<f64>
pub async fn incrbyfloat( &self, key: impl Into<String>, increment: f64, ) -> Result<f64>
INCRBYFLOAT - 将键的浮点数值增加指定数量
§参数
key: 键increment: 增量(可以是负数)
§返回
Ok(f64): 增加后的值
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
client.set("price", "10.5").await?;
let new_price = client.incrbyfloat("price", 2.3).await?; // 12.8
Ok(())
}Sourcepub async fn psetex(
&self,
key: impl Into<String>,
milliseconds: i64,
value: impl Into<String>,
) -> Result<()>
pub async fn psetex( &self, key: impl Into<String>, milliseconds: i64, value: impl Into<String>, ) -> Result<()>
PSETEX - 设置键值并指定毫秒级过期时间
§参数
key: 键milliseconds: 过期时间(毫秒)value: 值
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
// 设置键值,100 毫秒后过期
client.psetex("session", 100, "data").await?;
Ok(())
}Sourcepub async fn hset(
&self,
key: impl Into<String>,
field: impl Into<String>,
value: impl Into<String>,
) -> Result<bool>
pub async fn hset( &self, key: impl Into<String>, field: impl Into<String>, value: impl Into<String>, ) -> Result<bool>
Sourcepub async fn hget(
&self,
key: impl Into<String>,
field: impl Into<String>,
) -> Result<Option<String>>
pub async fn hget( &self, key: impl Into<String>, field: impl Into<String>, ) -> Result<Option<String>>
Sourcepub async fn hexists(
&self,
key: impl Into<String>,
field: impl Into<String>,
) -> Result<bool>
pub async fn hexists( &self, key: impl Into<String>, field: impl Into<String>, ) -> Result<bool>
Sourcepub async fn hmset(
&self,
key: impl Into<String>,
fields: &[(String, String)],
) -> Result<()>
pub async fn hmset( &self, key: impl Into<String>, fields: &[(String, String)], ) -> Result<()>
HMSET - 批量设置哈希表的多个字段
Sourcepub async fn hmget(
&self,
key: impl Into<String>,
fields: &[String],
) -> Result<Vec<Option<String>>>
pub async fn hmget( &self, key: impl Into<String>, fields: &[String], ) -> Result<Vec<Option<String>>>
Sourcepub async fn hincrby(
&self,
key: impl Into<String>,
field: impl Into<String>,
increment: i64,
) -> Result<i64>
pub async fn hincrby( &self, key: impl Into<String>, field: impl Into<String>, increment: i64, ) -> Result<i64>
HINCRBY - 将哈希表字段的整数值增加指定数量
Sourcepub async fn hincrbyfloat(
&self,
key: impl Into<String>,
field: impl Into<String>,
increment: f64,
) -> Result<f64>
pub async fn hincrbyfloat( &self, key: impl Into<String>, field: impl Into<String>, increment: f64, ) -> Result<f64>
HINCRBYFLOAT - 将哈希表字段的浮点数值增加指定数量
Sourcepub async fn lrange(
&self,
key: impl Into<String>,
start: i64,
stop: i64,
) -> Result<Vec<String>>
pub async fn lrange( &self, key: impl Into<String>, start: i64, stop: i64, ) -> Result<Vec<String>>
Sourcepub async fn lset(
&self,
key: impl Into<String>,
index: i64,
value: impl Into<String>,
) -> Result<()>
pub async fn lset( &self, key: impl Into<String>, index: i64, value: impl Into<String>, ) -> Result<()>
LSET - 设置列表指定索引的元素值
Sourcepub async fn ltrim(
&self,
key: impl Into<String>,
start: i64,
stop: i64,
) -> Result<()>
pub async fn ltrim( &self, key: impl Into<String>, start: i64, stop: i64, ) -> Result<()>
LTRIM - 修剪列表,仅保留指定范围内的元素
Sourcepub async fn linsert(
&self,
key: impl Into<String>,
before_after: &str,
pivot: impl Into<String>,
value: impl Into<String>,
) -> Result<i64>
pub async fn linsert( &self, key: impl Into<String>, before_after: &str, pivot: impl Into<String>, value: impl Into<String>, ) -> Result<i64>
LINSERT - 在列表的指定元素前或后插入新元素
§参数
key: 键before_after: “BEFORE” 或 “AFTER”pivot: 参考元素value: 要插入的值
§返回
Ok(i64): 插入后列表的长度,-1 表示 pivot 不存在
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
client.rpush("mylist", &["a".to_string(), "c".to_string()]).await?;
client.linsert("mylist", "BEFORE", "c", "b").await?; // ["a", "b", "c"]
Ok(())
}Sourcepub async fn lrem(
&self,
key: impl Into<String>,
count: i64,
value: impl Into<String>,
) -> Result<i64>
pub async fn lrem( &self, key: impl Into<String>, count: i64, value: impl Into<String>, ) -> Result<i64>
LREM - 删除列表中的指定元素
§参数
key: 键count: 删除数量- count > 0: 从头到尾删除 count 个匹配元素
- count < 0: 从尾到头删除 |count| 个匹配元素
- count = 0: 删除所有匹配元素
value: 要删除的值
§返回
Ok(i64): 被删除元素的数量
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
client.rpush("mylist", &["a".to_string(), "b".to_string(), "a".to_string()]).await?;
let removed = client.lrem("mylist", 2, "a").await?; // 删除 2 个 "a"
Ok(())
}Sourcepub async fn rpoplpush(
&self,
source: impl Into<String>,
destination: impl Into<String>,
) -> Result<Option<String>>
pub async fn rpoplpush( &self, source: impl Into<String>, destination: impl Into<String>, ) -> Result<Option<String>>
RPOPLPUSH - 从源列表尾部弹出元素并插入到目标列表头部
§参数
source: 源列表键destination: 目标列表键
§返回
Ok(Some(String)): 被移动的元素Ok(None): 源列表为空
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
client.rpush("list1", &["a".to_string(), "b".to_string()]).await?;
let elem = client.rpoplpush("list1", "list2").await?; // "b"
Ok(())
}Sourcepub async fn blpop(
&self,
keys: &[String],
timeout: i64,
) -> Result<Option<(String, String)>>
pub async fn blpop( &self, keys: &[String], timeout: i64, ) -> Result<Option<(String, String)>>
BLPOP - 阻塞式地从列表头部弹出元素
§参数
keys: 键列表(按顺序检查)timeout: 超时时间(秒),0 表示无限等待
§返回
Ok(Some((String, String))): (键名, 元素值)Ok(None): 超时
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
let result = client.blpop(&["queue1".to_string(), "queue2".to_string()], 5).await?;
if let Some((key, value)) = result {
println!("从 {} 弹出: {}", key, value);
}
Ok(())
}Sourcepub async fn brpop(
&self,
keys: &[String],
timeout: i64,
) -> Result<Option<(String, String)>>
pub async fn brpop( &self, keys: &[String], timeout: i64, ) -> Result<Option<(String, String)>>
BRPOP - 阻塞式地从列表尾部弹出元素
§参数
keys: 键列表(按顺序检查)timeout: 超时时间(秒),0 表示无限等待
§返回
Ok(Some((String, String))): (键名, 元素值)Ok(None): 超时
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
let result = client.brpop(&["queue1".to_string()], 10).await?;
Ok(())
}Sourcepub async fn smembers(&self, key: impl Into<String>) -> Result<Vec<String>>
pub async fn smembers(&self, key: impl Into<String>) -> Result<Vec<String>>
SMEMBERS - 获取集合的所有成员
Sourcepub async fn sismember(
&self,
key: impl Into<String>,
member: impl Into<String>,
) -> Result<bool>
pub async fn sismember( &self, key: impl Into<String>, member: impl Into<String>, ) -> Result<bool>
Sourcepub async fn smove(
&self,
source: impl Into<String>,
destination: impl Into<String>,
member: impl Into<String>,
) -> Result<bool>
pub async fn smove( &self, source: impl Into<String>, destination: impl Into<String>, member: impl Into<String>, ) -> Result<bool>
Sourcepub async fn sscan(
&self,
key: impl Into<String>,
cursor: i64,
pattern: Option<&str>,
count: Option<i64>,
) -> Result<(i64, Vec<String>)>
pub async fn sscan( &self, key: impl Into<String>, cursor: i64, pattern: Option<&str>, count: Option<i64>, ) -> Result<(i64, Vec<String>)>
Sourcepub async fn zscore(
&self,
key: impl Into<String>,
member: impl Into<String>,
) -> Result<Option<f64>>
pub async fn zscore( &self, key: impl Into<String>, member: impl Into<String>, ) -> Result<Option<f64>>
Sourcepub async fn zrange(
&self,
key: impl Into<String>,
start: i64,
stop: i64,
) -> Result<Vec<String>>
pub async fn zrange( &self, key: impl Into<String>, start: i64, stop: i64, ) -> Result<Vec<String>>
Sourcepub async fn zrangebyscore(
&self,
key: impl Into<String>,
min: f64,
max: f64,
) -> Result<Vec<String>>
pub async fn zrangebyscore( &self, key: impl Into<String>, min: f64, max: f64, ) -> Result<Vec<String>>
Sourcepub async fn zcount(
&self,
key: impl Into<String>,
min: f64,
max: f64,
) -> Result<i64>
pub async fn zcount( &self, key: impl Into<String>, min: f64, max: f64, ) -> Result<i64>
ZCOUNT - 计算分数范围内的成员数量
Sourcepub async fn zincrby(
&self,
key: impl Into<String>,
increment: f64,
member: impl Into<String>,
) -> Result<f64>
pub async fn zincrby( &self, key: impl Into<String>, increment: f64, member: impl Into<String>, ) -> Result<f64>
Sourcepub async fn zrank(
&self,
key: impl Into<String>,
member: impl Into<String>,
) -> Result<Option<i64>>
pub async fn zrank( &self, key: impl Into<String>, member: impl Into<String>, ) -> Result<Option<i64>>
Sourcepub async fn zrevrank(
&self,
key: impl Into<String>,
member: impl Into<String>,
) -> Result<Option<i64>>
pub async fn zrevrank( &self, key: impl Into<String>, member: impl Into<String>, ) -> Result<Option<i64>>
Sourcepub async fn zrevrange(
&self,
key: impl Into<String>,
start: i64,
stop: i64,
) -> Result<Vec<String>>
pub async fn zrevrange( &self, key: impl Into<String>, start: i64, stop: i64, ) -> Result<Vec<String>>
Sourcepub async fn zrange_with_scores(
&self,
key: impl Into<String>,
start: i64,
stop: i64,
) -> Result<Vec<(String, f64)>>
pub async fn zrange_with_scores( &self, key: impl Into<String>, start: i64, stop: i64, ) -> Result<Vec<(String, f64)>>
Sourcepub async fn zrevrange_with_scores(
&self,
key: impl Into<String>,
start: i64,
stop: i64,
) -> Result<Vec<(String, f64)>>
pub async fn zrevrange_with_scores( &self, key: impl Into<String>, start: i64, stop: i64, ) -> Result<Vec<(String, f64)>>
Sourcepub async fn zremrangebyrank(
&self,
key: impl Into<String>,
start: i64,
stop: i64,
) -> Result<i64>
pub async fn zremrangebyrank( &self, key: impl Into<String>, start: i64, stop: i64, ) -> Result<i64>
Sourcepub async fn zremrangebyscore(
&self,
key: impl Into<String>,
min: f64,
max: f64,
) -> Result<i64>
pub async fn zremrangebyscore( &self, key: impl Into<String>, min: f64, max: f64, ) -> Result<i64>
Sourcepub async fn zscan(
&self,
key: impl Into<String>,
cursor: i64,
pattern: Option<&str>,
count: Option<i64>,
) -> Result<(i64, Vec<(String, f64)>)>
pub async fn zscan( &self, key: impl Into<String>, cursor: i64, pattern: Option<&str>, count: Option<i64>, ) -> Result<(i64, Vec<(String, f64)>)>
Sourcepub async fn scan(
&self,
cursor: i64,
pattern: Option<&str>,
count: Option<i64>,
) -> Result<(i64, Vec<String>)>
pub async fn scan( &self, cursor: i64, pattern: Option<&str>, count: Option<i64>, ) -> Result<(i64, Vec<String>)>
SCAN - 增量式迭代数据库中的所有键
生产安全的 KEYS 替代方案,不会阻塞 Redis 服务器。
§参数
cursor: 游标(初始传 0,使用返回的游标继续迭代)pattern: 可选的键名匹配模式(如Some("user:*"))count: 可选的每批返回数量提示
§返回
Ok((i64, Vec<String>)): (下一游标, 本批键列表)- 游标为 0 表示完整迭代完成
§示例
let mut cursor = 0i64;
loop {
let (next, keys) = client.scan(cursor, Some("user:*"), Some(100)).await?;
// 处理 keys...
cursor = next;
if cursor == 0 { break; }
}Sourcepub async fn publish(
&self,
channel: impl Into<String>,
message: impl Into<String>,
) -> Result<i64>
pub async fn publish( &self, channel: impl Into<String>, message: impl Into<String>, ) -> Result<i64>
Sourcepub async fn health_check(&self) -> Result<bool>
pub async fn health_check(&self) -> Result<bool>
健康检查 - 验证 Redis 连接是否正常
执行 PING 命令检查 Redis 服务可达性。连接异常时不抛错误,返回 Ok(false)。
§返回
Ok(true): Redis 连接正常Ok(false): PING 响应异常Err(DbError): 无法获取连接
Sourcepub fn pool_status(&self) -> PoolStatus
pub fn pool_status(&self) -> PoolStatus
Sourcepub fn script(&self, code: &str) -> Script
pub fn script(&self, code: &str) -> Script
创建 Lua 脚本对象
返回 redis-rs 的原生 Script 类型,可用于执行 Lua 脚本。 Script 会自动处理 EVALSHA 和 EVAL 的回退机制。
§参数
code: Lua 脚本代码
§返回
redis::Script 对象
§示例
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
// 创建脚本:原子性地增加两个计数器
let script = client.script(
r#"
redis.call('INCR', KEYS[1])
redis.call('INCR', KEYS[2])
return redis.call('GET', KEYS[1])
"#
);
// 执行脚本
let result: String = client.eval_script(
&script,
&["counter1".to_string(), "counter2".to_string()],
&[]
).await?;
println!("counter1 的值: {}", result);
Ok(())
}Sourcepub async fn eval_script<T>(
&self,
script: &Script,
keys: &[String],
args: &[String],
) -> Result<T>where
T: FromRedisValue,
pub async fn eval_script<T>(
&self,
script: &Script,
keys: &[String],
args: &[String],
) -> Result<T>where
T: FromRedisValue,
执行 Lua 脚本
使用 redis::Script 执行 Lua 脚本,自动处理 EVALSHA 和 EVAL 的回退。 脚本内的所有操作都是原子性的。
§参数
script: 脚本对象(通过script()方法创建)keys: KEYS 参数列表(在脚本中通过 KEYS[1], KEYS[2] 访问)args: ARGV 参数列表(在脚本中通过 ARGV[1], ARGV[2] 访问)
§返回
Ok(T): 脚本执行成功,返回类型化结果Err(DbError): 脚本执行失败
§示例:原子性计数器增加
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
let script = client.script(
r#"
local current = redis.call('GET', KEYS[1])
if not current then
current = 0
end
local new_value = tonumber(current) + tonumber(ARGV[1])
redis.call('SET', KEYS[1], new_value)
return new_value
"#
);
let result: i64 = client.eval_script(
&script,
&["my_counter".to_string()],
&["10".to_string()]
).await?;
println!("新值: {}", result);
Ok(())
}§示例:条件更新(乐观锁)
use yang_db::RedisClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RedisClient::connect("redis://127.0.0.1:6379").await?;
// 只有当余额足够时才扣减
let script = client.script(
r#"
local balance = tonumber(redis.call('GET', KEYS[1]) or 0)
local amount = tonumber(ARGV[1])
if balance >= amount then
redis.call('DECRBY', KEYS[1], amount)
return 1
else
return 0
end
"#
);
let success: i64 = client.eval_script(
&script,
&["user:1000:balance".to_string()],
&["100".to_string()]
).await?;
if success == 1 {
println!("扣款成功");
} else {
println!("余额不足");
}
Ok(())
}§性能优化
- 首次执行时,脚本会被发送到 Redis 服务器并缓存
- 后续执行使用 EVALSHA 命令,只传输脚本的 SHA1 哈希值
- 如果脚本不在缓存中,自动回退到 EVAL 命令
Trait Implementations§
Source§impl Clone for RedisClient
impl Clone for RedisClient
Source§fn clone(&self) -> RedisClient
fn clone(&self) -> RedisClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for RedisClient
impl !RefUnwindSafe for RedisClient
impl Send for RedisClient
impl Sync for RedisClient
impl Unpin for RedisClient
impl UnsafeUnpin for RedisClient
impl !UnwindSafe for RedisClient
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more