Rust锚属性状态管理库anchor-attribute-state的使用,实现高效属性状态管理与同步
Rust锚属性状态管理库anchor-attribute-state的使用,实现高效属性状态管理与同步
安装
在项目目录中运行以下Cargo命令:
cargo add anchor-attribute-state
或者在你的Cargo.toml中添加以下行:
anchor-attribute-state = "0.26.0"
完整示例代码
以下是一个使用anchor-attribute-state进行属性状态管理和同步的完整示例:
use anchor_attribute_state::prelude::*;
// 定义一个带有状态属性的结构体
#[derive(State)]
struct UserAccount {
#[state] // 标记为需要状态管理的属性
name: String,
#[state(sync)] // 标记为需要同步的状态属性
balance: f64,
age: u8, // 普通属性,不参与状态管理
}
impl UserAccount {
// 创建一个新账户
fn new(name: String, balance: f64, age: u8) -> Self {
Self {
name,
balance,
age,
}
}
}
fn main() {
// 初始化用户账户
let mut user = UserAccount::new("Alice".to_string(), 100.0, 30);
// 修改状态属性会自动触发状态管理
user.name = "Bob".to_string(); // 状态变更会被记录
user.balance = 150.0; // 同步属性变更会被记录并准备同步
// 普通属性修改不受影响
user.age = 31;
// 获取状态变化
let name_changes = user.name_state().changes();
let balance_changes = user.balance_state().changes();
println!("Name changes: {:?}", name_changes);
println!("Balance changes: {:?}", balance_changes);
// 同步状态
if let Some(latest_balance) = user.balance_state().latest() {
// 这里可以添加同步到远程的逻辑
println!("Syncing balance: {}", latest_balance);
user.balance_state().mark_synced(); // 标记为已同步
}
// 重置状态跟踪
user.name_state().reset();
user.balance_state().reset();
}
功能说明
#[state]
属性宏用于标记需要状态管理的字段#[state(sync)]
表示该字段需要同步到远程- 自动跟踪字段变化并记录变更历史
- 提供方法获取变更状态和重置状态跟踪
- 对于需要同步的字段,提供标记同步状态的方法
所有者
- Armani Ferrante
- solana-foundation-tech
1 回复
Rust锚属性状态管理库anchor-attribute-state使用指南
概述
anchor-attribute-state
是一个用于Rust的状态管理库,它通过属性注解的方式简化状态管理,实现高效的属性状态管理与同步。这个库特别适合需要跟踪和同步多个属性状态的应用程序。
主要特性
- 通过属性宏简化状态管理
- 自动状态跟踪和变更检测
- 高效的状态同步机制
- 支持派生和组合状态
- 线程安全的设计
安装
在Cargo.toml中添加依赖:
[dependencies]
anchor-attribute-state = "0.3"
基本用法
1. 定义状态结构体
use anchor_attribute_state::State;
#[derive(State)]
struct User {
#[state] // 标记需要跟踪状态的字段
name: String,
#[state]
age: u32,
#[state]
is_active: bool,
}
2. 创建状态实例并监听变化
use anchor_attribute_state::StateManager;
let user = User {
name: "Alice".to_string(),
age: 30,
is_active: true,
};
let mut manager = StateManager::new(user);
// 订阅状态变化
manager.subscribe(|changed: &User| {
println!("State changed: {:?}", changed);
});
// 修改状态
manager.update(|user| {
user.name = "Bob".to_string();
user.age += 1;
});
高级用法
1. 选择性监听特定属性
#[derive(State)]
struct Settings {
#[state(watch)] // 只监听标记了watch的属性
theme: String,
#[state]
font_size: u32,
#[state(watch)]
notifications: bool,
}
let settings = Settings {
theme: "dark".to_string(),
font_size: 14,
notifications: true,
};
let mut manager = StateManager::new(settings);
// 只监听标记了watch的属性变化
manager.subscribe(|changed: &Settings| {
println!("Watched properties changed: {:?}", changed);
});
// 只有修改theme或notifications会触发回调
manager.update(|s| {
s.theme = "light".to_string(); // 会触发回调
s.font_size = 16; // 不会触发回调
});
2. 派生状态
#[derive(State)]
struct ShoppingCart {
#[state]
items: Vec<String>,
#[state(derived = "total_price")] // 标记为派生状态
prices: Vec<f64>,
}
impl ShoppingCart {
// 派生状态的计算方法
fn total_price(&self) -> f64 {
self.prices.iter().sum()
}
}
let cart = ShoppingCart {
items: vec!["Apple".to_string(), "Banana".to_string()],
prices: vec![0.99, 0.59],
};
let mut manager = StateManager::new(cart);
manager.subscribe(|changed: &ShoppingCart| {
println!("New total price: ${:.2}", changed.total_price());
});
manager.update(|cart| {
cart.items.push("Orange".to_string());
cart.prices.push(1.29);
});
3. 嵌套状态管理
#[derive(State)]
struct Address {
#[state]
street: String,
#[state]
city: String,
}
#[derive(State)]
struct UserProfile {
#[state]
name: String,
#[state(nested)] // 嵌套状态管理
address: Address,
}
let profile = UserProfile {
name: "Charlie".to_string(),
address: Address {
street: "123 Main St".to_string(),
city: "Metropolis".to_string(),
},
};
let mut manager = StateManager::new(profile);
manager.subscribe(|changed: &UserProfile| {
println!("Profile updated: {:?}", changed);
});
// 修改嵌套属性也会触发更新
manager.update(|profile| {
profile.address.city = "Gotham".to_string();
});
性能优化技巧
- 对于频繁更新的状态,使用
#[state(skip)]
跳过不必要的派生计算 - 批量更新使用
manager.batch_update
减少通知次数 - 对大型集合考虑使用
#[state(lazy)]
延迟计算
#[derive(State)]
struct Analytics {
#[state(skip)] // 跳过自动跟踪
raw_data: Vec<f64>,
#[state(derived = "stats", lazy)] // 延迟计算
processed: bool,
}
impl Analytics {
fn stats(&self) -> (f64, f64) {
let mean = self.raw_data.iter().sum::<f64>() / self.raw_data.len() as f64;
let variance = self.raw_data.iter()
.map(|x| (x - mean).powi(2))
.sum::<f64>() / self.raw_data.len() as f64;
(mean, variance.sqrt())
}
}
注意事项
- 确保状态类型实现
PartialEq
以便检测变化 - 避免在状态回调中修改状态,这可能导致无限循环
- 对于多线程使用,确保状态类型是
Send + Sync
完整示例demo
下面是一个结合多种功能的完整示例:
use anchor_attribute_state::{State, StateManager};
// 定义嵌套状态
#[derive(Debug, State, PartialEq)]
struct Location {
#[state]
latitude: f64,
#[state]
longitude: f64,
}
// 主状态结构体
#[derive(Debug, State, PartialEq)]
struct AppState {
#[state]
counter: u32,
#[state(watch)] // 只监听重要属性
theme: String,
#[state(nested)] // 嵌套状态
location: Location,
#[state(derived = "stats")] // 派生状态
data_points: Vec<f64>,
}
impl AppState {
// 派生状态计算方法
fn stats(&self) -> (f64, usize) {
let sum = self.data_points.iter().sum::<f64>();
let count = self.data_points.len();
(sum, count)
}
}
fn main() {
// 初始化状态
let state = AppState {
counter: 0,
theme: "dark".to_string(),
location: Location {
latitude: 40.7128,
longitude: -74.0060,
},
data_points: vec![1.0, 2.0, 3.0],
};
let mut manager = StateManager::new(state);
// 订阅状态变化
manager.subscribe(|changed: &AppState| {
println!("State changed - Counter: {}, Theme: {}",
changed.counter, changed.theme);
let (sum, count) = changed.stats();
println!("Data stats: sum={:.2}, count={}", sum, count);
});
// 批量更新
manager.batch_update(|state| {
state.counter += 1;
state.theme = "light".to_string();
state.location.latitude = 34.0522;
state.data_points.push(4.0);
});
// 单独更新
manager.update(|state| {
state.counter += 1;
});
}
这个完整示例展示了:
- 基本状态管理
- 选择性监听(watch)
- 嵌套状态管理
- 派生状态
- 批量更新
- 状态变化订阅
anchor-attribute-state
通过简洁的属性和高效的变更检测机制,为Rust应用程序提供了灵活而强大的状态管理解决方案。