【问题标题】:Rust type alias causes lifetime problemsRust 类型别名会导致生命周期问题
【发布时间】:2020-09-25 11:57:04
【问题描述】:

我试图通过引入类型别名来缩短函数签名。 参数的类型说明是这样的

writer: Arc<Mutex<&mut (dyn AsyncWrite + Unpin + Send + Sync)>>  // working

我认为可以通过引入这种类型别名来缩短它

pub type RefAsyncWriter<'a> = &'a mut (dyn AsyncWrite + Unpin + Send + Sync);

所以类型参数就变成了

writer: Arc<Mutex<RefAsyncWriter>>  // error[E0726]: implicit elided lifetime not allowed here

不幸的是,这种变化给我带来了一生的麻烦。

这里我做了一个简单的例子

use tokio::io::AsyncWrite;
use tokio::fs::File;
use std::sync::{Arc,Mutex};
use std::path::PathBuf;
pub type RefAsyncWriter<'a> = &'a mut (dyn AsyncWrite + Unpin + Send + Sync);

#[tokio::main]
async fn main() {
    let f = File::create(PathBuf::from("/tmp/test.txt")).await.unwrap();
    w(Arc::new(Mutex::new(&mut f)));
}

async fn w(writer: Arc<Mutex<RefAsyncWriter>>) {
  // TODO
}

结果如下

Compiling playground v0.0.1 (/playground)
error[E0726]: implicit elided lifetime not allowed here
  --> src/main.rs:13:31
   |
13 | async fn w (writer: Arc<Mutex<RefAsyncWriter>>) {}
   |                               ^^^^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`

error: aborting due to previous error

(见:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=eb46708a9df66efa0de419a8d98490cf

如果有人可以向我解释 (1) 是否有办法让它工作,也许 (2) 为什么类型别名实际上会对编译器产生如此大的帮助。

非常感谢。

【问题讨论】:

    标签: rust lifetime


    【解决方案1】:

    由于在类型别名中引入了显式的生命周期'a,所以在使用该类型时需要指定。

    async fn w<'a>(writer: Arc<Mutex<RefAsyncWriter<'a>>>) {}
    

    它似乎在你提供的操场上工作。

    正如编译器所建议的,匿名 litetime 是等价的。

    async fn w(writer: Arc<Mutex<RefAsyncWriter<'_>>>) {}
    

    您的函数的原始版本(在writer: 之后写下的很长的类型在某种程度上相当于this documentation 中的print1()print2()print3()。 如果你引入一个引用作为参数,那么这个函数必然存在一个生命周期参数;当这一生不会混淆时,省略只是为节省一些击键带来一些安慰。

    当定义一个包含引用的类型别名时,编译器希望我们明确生命周期,可能是为了防止使用此类型别名的人忘记其中有一个引用隐藏。 然后,使用此类型别名需要&lt;'...&gt; 表示法。 但同样,当使用时不会混淆时,匿名生命周期&lt;'_&gt; 会节省一些击键,避免两次写入&lt;'a&gt;(在函数名之后和参数中)。

    【讨论】:

    • 非常感谢,这行得通。我实际上看到了编译器的建议,但我无法真正弄清楚将丢失的生命周期放在哪里。老实说,我仍然不明白为什么它会这样工作,但无论如何它暂时解决了我当前的问题。
    • 是的,编译器强制我们在此处显式以便不在类型别名中隐藏引用实际上是有道理的。一开始有点令人困惑,但在某些时候,如果这里没有明确指定生命周期,可能会出现更令人困惑的情况。再次感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 2019-04-08
    • 1970-01-01
    • 2013-07-03
    相关资源
    最近更新 更多