rust - 为什么在解构变量后无法调用方法,但直接访问该字段却可以调用方法?

标签 rust pattern-matching lifetime

The following未编译:

use std::any::Any;

pub trait CloneBox: Any {
    fn clone_box(&self) -> Box<dyn CloneBox>;
}

impl<T> CloneBox for T
where
    T: Any + Clone,
{
    fn clone_box(&self) -> Box<dyn CloneBox> {
        Box::new(self.clone())
    }
}

struct Foo(Box<dyn CloneBox>);

impl Clone for Foo {
    fn clone(&self) -> Self {
        let Foo(b) = self;
        Foo(b.clone_box())
    }
}

错误消息:

error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements
  --> src/lib.rs:20:17
   |
20 |         let Foo(b) = self;
   |                 ^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 19:5...
  --> src/lib.rs:19:5
   |
19 | /     fn clone(&self) -> Self {
20 | |         let Foo(b) = self;
21 | |         Foo(b.clone_box())
22 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:20:17
   |
20 |         let Foo(b) = self;
   |                 ^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `&std::boxed::Box<dyn CloneBox>` will meet its required lifetime bounds
  --> src/lib.rs:21:15
   |
21 |         Foo(b.clone_box())
   |  

但是,如果将 clone() 中的代码从 Foo(b.clone_box()) 更改为 Foo(self.0.clone_box()),编译没有问题。理论上,字段访问应该和模式匹配一​​样,但是为什么模式匹配会存在生命周期问题呢?

在我的真实代码中,数据位于枚举中,而不是结构中,因此模式匹配是唯一的选择。

最佳答案

TL;DR:在调用方法之前取消引用该值:

Foo((*b).clone_box())

let Foo(b) = self ,类型 b&Box<(dyn CloneBox + 'static)> 。方法调用有效

Foo(<&Box<dyn CloneBox + 'static> as CloneBox>::clone_box(&b))

该值不能成为特征对象Box<dyn CloneBox + 'static>因为本地引用。有趣的是,我相信如果编译器允许的话,这将递归地使用毯子实现。

self.0.clone_box() ,方法调用有效:

Foo(<dyn CloneBox as CloneBox>::clone_box(&**b)

我们可以将其写为 Foo((&**b).clone_box())明确地说,但由于没有中间实现,Foo((*b).clone_box())就足够了。

另请参阅:

关于rust - 为什么在解构变量后无法调用方法,但直接访问该字段却可以调用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54757677/

相关文章:

scala - 将字符串匹配为 Seq[Char] 的模式

compiler-errors - 从方法内部的模式匹配返回时在当前范围内找不到关联类型

reference - 有没有办法返回对函数中创建的变量的引用?

docker - SSL 证书验证适用于 Docker,而不适用于 Kubernetes

rust - 如何从使用rust 连接scylladb

java - url 路径的模式匹配

rust - 为什么不能在同一结构中存储值和对该值的引用?

optimization - Rust : functional v imperative approach 中的 Collat​​z 猜想

iterator - 从函数返回的迭代器的生存期要求冲突

struct - 如何在结构中存储clap::ArgMatches?