繁体   English   中英

如何匹配Arc内的选项?

[英]How to match on an Option inside an Arc?

Arc<T>文档说:

Arc<T>自动解引用T (通过Deref特征),因此您可以在Arc<T>类型的值上调用T的方法。

但有没有办法允许匹配Option -al类型?

这是一个简单的例子:

use std::sync::Arc;

fn main() {
    let foo: Arc<Option<String>> = Arc::new(Some("hello".to_string()));

    if foo.is_some() {
        println!("{}", foo.unwrap());
    }

    match foo {
        Some(hello) => {
            println!("{}", hello);
        }
        None => {}
    }
}

编译器错误是:

error[E0308]: mismatched types
  --> src/main.rs:11:9
   |
11 |         Some(hello) => {
   |         ^^^^^^^^^^^ expected struct `std::sync::Arc`, found enum `std::option::Option`
   |
   = note: expected type `std::sync::Arc<std::option::Option<std::string::String>>`
              found type `std::option::Option<_>`

error[E0308]: mismatched types
  --> src/main.rs:14:9
   |
14 |         None => {}
   |         ^^^^ expected struct `std::sync::Arc`, found enum `std::option::Option`
   |
   = note: expected type `std::sync::Arc<std::option::Option<std::string::String>>`
              found type `std::option::Option<_>`

不,您无法在Arc内部的Option上进行匹配。 要在模式匹配中使用类型,必须可以使用该类型的实现,但Arc的实现不是公共的。


在某些情况下,您可以执行某种转换以匹配引用

例如,由于Arc<T>实现Deref ,您可以使用*运算符通过Arc<T>取消引用到底层T 由于这种匹配具有一些符合人体工程学的语法 ,因此您可以在不获取所有权的情况下对Option内部的值进行引用:

match *foo {
    Some(ref hello) => {
        println!("{}", hello);
    }
    None => {}
}

您还可以使用Option::as_ref&Option<T>自动Arc<T>通过Deref 取消引用 )转换为Option<&T>

match Option::as_ref(&foo) {
    Some(hello) => {
        println!("{}", hello);
    }
    None => {}
}

不幸的是,您不能只调用.as_ref()因为特征方法AsRef::as_ref优先。

在这两种情况下,它更习惯使用if let你只关心比赛的武器之一:

if let Some(ref hello) = *foo {
    println!("{}", hello);
}

第一个println通过了编译器的早期阶段,但它在稍后阶段被借用检查器标记。 第二个println更容易修复。

use std::sync::Arc;

fn main() {
    let foo: Arc<Option<String>> = Arc::new(Some("hello".to_string()));

    if foo.is_some() {
        let f1: &Option<String> = foo.as_ref();
        let f2: Option<&String> = f1.as_ref();
        let f3: &String = f2.unwrap();
        println!("{}", f3);

        println!("{}", foo.as_ref().as_ref().unwrap())
    }

    match *foo {
        Some(ref hello) => {
            println!("{}", hello);
        }
        None => {}
    }
}

第一个println容易混淆地使用两个as_ref()方法调用。 第一个as_ref作用于Arc ,类型签名为Fn(&Arc<Option<String>>) -> &Option<String> 第二个作用于Option ,类型签名为Fn(&Option<String>) -> Option<&String>

操场

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM