锈蚀类型的别名会导致使用寿命问题



我试图通过引入类型别名来缩短函数签名。参数的类型规范看起来像这个

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=调试&edition=2018&gist=eb46708a9df66efa0de419a8d98490cf(

如果有人能向我解释(1(是否有办法做到这一点,也许(2(为什么类型别名实际上对编译器有如此大的影响,那将是非常有帮助的。

提前非常感谢。

由于在类型别名中引入了显式生存期'a,因此在使用此类型时需要指定它。

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

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

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

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

函数的原始版本(在writer:之后写下非常长的类型(在某种程度上等同于本文档中的print1()print2()print3()。如果引入引用作为参数,则此函数必然存在生存期参数;省略只带来了一些安慰,在这个生命周期中不可能出现混淆的情况下,可以节省一些按键。

当定义包含引用的类型别名时,编译器希望我们明确生存期,可能是为了防止使用此类型别名的人忘记内部隐藏了引用。然后,使用此类型别名需要<'...>表示法。但是,当使用时不可能出现混淆时,匿名生存期<'_>可以节省一些按键,避免两次写入<'a>(在函数名之后和参数中(。

相关内容

最新更新