Rust可选值处理库optional的使用,提供高效安全的Option类型扩展功能

Rust可选值处理库optional的使用,提供高效安全的Option类型扩展功能

Optional库旨在提供一些类似Option<_>的值,但允许空间优化的表示形式。

当前版本包含一个OptionBool类型,它的工作方式非常类似于Option<bool>(实际上大部分复制了它的接口)。只有在Option<bool>会接收或返回另一个Option<bool>的地方,使用_bool前缀来接收/返回OptionBool

请注意,由于内部转换,通常不可能创建iter_mut()as_mut_slice()方法,因此这些方法不受支持。

OptionBool不仅比Option<bool>提高了空间效率,在基准测试中大多数方法也表现得更快。

示例代码

use optional::OptionBool;

fn main() {
    // 创建OptionBool
    let some_true = OptionBool::some(true);
    let some_false = OptionBool::some(false);
    let none = OptionBool::none();
    
    // 检查值
    assert_eq!(some_true.is_some(), true);
    assert_eq!(some_false.is_some(), true);
    assert_eq!(none.is_some(), false);
    
    // 获取值
    assert_eq!(some_true.unwrap(), true);
    assert_eq!(some_false.unwrap(), false);
    
    // 使用bool前缀的方法
    let and_result = some_true.and_bool(some_false);
    assert_eq!(and_result.unwrap(), false);
    
    let or_result = some_true.or_bool(none);
    assert_eq!(or_result.unwrap(), true);
    
    // 转换
    let opt: Option<bool> = some_true.into();
    assert_eq!(opt, Some(true));
    
    let from_opt = OptionBool::from(上述示例展示了optional库的基本用法,下面是更完整的示例demo,展示了更多实际应用场景:

```rust
use optional::{OptionBool, Optioned};

fn main() {
    // 1. OptionBool的高级用法示例
    let flag = OptionBool::some(true);
    
    // 使用map转换值
    let mapped = flag.map(|b| if b { "是" } else { "否" });
    assert_eq!(mapped, Some("是"));
    
    // 使用and_then链式调用
    let result = flag.and_bool(OptionBool::some(false))
                    .or_bool(OptionBool::some(true));
    assert_eq!(result.unwrap(), false);
    
    // 2. Optioned<T>的综合应用
    // 处理可能为None的数值计算
    let value1 = Optioned::some(10i32);
    let value2 = Optioned::<i32>::none();
    
    let sum = value1.unwrap_or(0) + value2.unwrap_or(0);
    assert_eq!(sum, 10);
    
    // 使用filter过滤值
    let filtered = value1.filter(|&x| x > 5);
    assert_eq!(filtered.unwrap(), 10);
    
    // 3. 自定义类型的Optioned使用
    #[derive(Debug, PartialEq)]
    enum Status {
        Active,
        Inactive,
        Terminated
    }
    
    impl optional::Noned for Status {
        fn noned() -> Self {
            Status::Terminated // 使用Terminated作为None值
        }
    }
    
    let active = Optioned::some(Status::Active);
    let none_status = Optioned::<Status>::none();
    
    match active.as_ref() {
        Optioned::Some(Status::Active) => println!("活跃状态"),
        _ => println!("其他状态")
    }
    
    // 4. 集合中使用OptionBool/Optioned
    let bool_options = vec![
        OptionBool::some(true),
        OptionBool::none(),
        OptionBool::some(false)
    ];
    
    let int_options: Vec<Optioned<i32>> = vec![
        Optioned::some(1),
        Optioned::none(),
        Optioned::some(3)
    ];
    
    // 处理集合中的可选值
    let bool_count = bool_options.iter()
        .filter(|o| o.is_some())
        .count();
    assert_eq!(bool_count, 2);
    
    let int_sum: i32 = int_options.iter()
        .map(|o| o.unwrap_or(0))
        .sum();
    assert_eq!(int_sum, 4);
}

这个完整示例展示了optional库在实际应用中的多种用法:

  1. OptionBool的高级操作如map、and_then等
  2. Optioned<T>的数值处理
  3. 自定义类型的Optioned实现
  4. 在集合中使用可选值并进行处理

所有示例都遵循空间优化的原则,同时保持了与标准库Option类似的API设计,便于使用。


1 回复

Rust可选值处理库optional的使用指南

optional是一个Rust库,它为标准的Option类型提供了扩展功能,使可选值处理更加高效和安全。这个库提供了一系列实用方法来简化Option类型的常见操作。

安装

Cargo.toml中添加依赖:

[dependencies]
optional = "1.0"

主要功能

1. 链式调用

optional提供了更流畅的链式调用方法:

use optional::OptionExt;

let result = Some(5)
    .map(|x| x * 2)
    .and_then(|x| if x > 10 { Some(x) } else { None })
    .or_else(|| Some(20))
    .unwrap_or(0);

println!("{}", result); // 输出 20

2. 布尔操作

可以直接在Option上执行布尔操作:

use optional::OptionExt;

let a = Some(true);
let b = Some(false);

assert_eq!(a & b, Some(false));
assert_eq!(a | b, Some(true));
assert_eq!(!a, Some(false));

3. 解引用操作

方便地解引用包含引用的Option

use optional::OptionExt;

let x = 10;
let opt = Some(&x);

assert_eq!(opt.deref(), Some(10));

4. 转换操作

提供多种转换方法:

use optional::OptionExt;

let opt = Some("hello");

// 转换为Result
let res: Result<&str, &str> = opt.ok_or("error");
assert_eq!(res, Ok("hello"));

// 转换为Vec
let vec: Vec<&str> = opt.into_vec();
assert_eq!(vec, vec!["hello"]);

5. 高级组合

use optional::OptionExt;

let a = Some(5);
let b = Some(10);

// 合并两个Option
let sum = a.zip_with(b, |x, y| x + y);
assert_eq!(sum, Some(15));

// 过滤值
let filtered = a.filter(|&x| x > 3);
assert_eq!(filtered, Some(5));

实际应用示例

use optional::OptionExt;

struct User {
    name: Option<String>,
    age: Option<u32>,
    email: Option<String>,
}

fn get_user() -> Option<User> {
    Some(User {
        name: Some("Alice".to_string()),
        age: Some(30),
        email: None,
    })
}

fn main() {
    let message = get_user()
        .and_then(|user| user.name)
        .map(|name| format!("Hello, {}!", name))
        .unwrap_or_else(|| "Hello, guest!".to_string());

    println!("{}", message); // 输出 "Hello, Alice!"
    
    // 更复杂的条件处理
    let age_check = get_user()
        .and_then(|user| user.age)
        .filter(|&age| age >= 18)
        .map(|_| "Adult")
        .unwrap_or("Minor");
    
    println!("{}", age_check); // 输出 "Adult"
}

完整示例代码

下面是一个更完整的示例,展示了optional库的各种功能:

use optional::OptionExt;

fn main() {
    // 1. 链式调用示例
    let chain_result = Some(3)
        .map(|x| x * 3)                  // 3 * 3 = 9
        .filter(|&x| x > 5)              // 9 > 5,保留
        .and_then(|x| Some(x + 1))       // 9 + 1 = 10
        .or_else(|| Some(100))           // 已经有值10,不会执行
        .unwrap_or(0);                   // 最终值10
    
    println!("链式调用结果: {}", chain_result); // 输出 10

    // 2. 布尔操作示例
    let bool_a = Some(true);
    let bool_b = Some(false);
    
    println!("与操作: {:?}", bool_a & bool_b); // Some(false)
    println!("或操作: {:?}", bool_a | bool_b); // Some(true)
    println!("非操作: {:?}", !bool_a);         // Some(false)

    // 3. 解引用操作示例
    let value = 42;
    let opt_ref = Some(&value);
    println!("解引用前: {:?}", opt_ref);     // Some(&42)
    println!("解引用后: {:?}", opt_ref.deref()); // Some(42)

    // 4. 转换操作示例
    let text_opt = Some("Rust");
    let text_result: Result<&str, &str> = text_opt.ok_or("Error");
    let text_vec: Vec<&str> = text_opt.into_vec();
    
    println!("转换Result: {:?}", text_result); // Ok("Rust")
    println!("转换Vec: {:?}", text_vec);      // ["Rust"]

    // 5. 高级组合示例
    let num_a = Some(8);
    let num_b = Some(2);
    
    let combined = num_a.zip_with(num_b, |a, b| a * b);
    println!("数字相乘: {:?}", combined); // Some(16)
    
    let filtered = num_a.filter(|&x| x > 10);
    println!("过滤结果: {:?}", filtered); // None

    // 实际应用示例
    #[derive(Debug)]
    struct Product {
        id: Option<u32>,
        name: Option<String>,
        price: Option<f64>,
    }

    let product = Some(Product {
        id: Some(123),
        name: Some("Rust Book".to_string()),
        price: Some(29.99),
    });

    let discount_price = product
        .and_then(|p| p.price)
        .map(|price| price * 0.8) // 8折
        .unwrap_or(0.0);
    
    println!("折扣价格: {:.2}", discount_price); // 23.99
}

optional库通过扩展Option的方法,使得Rust中的可选值处理更加简洁和表达力强,特别适合需要大量处理Option类型的场景。

回到顶部