我试图通过引入类型别名来缩短函数签名。参数的类型规范看起来像这个
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>
(在函数名之后和参数中(。