特征相关类型的其他"静态"要求?



考虑下一个函数,例如:

fn print(input: &dyn Display) {
println!("{}", input);
}

它运行良好,正如预期的那样。

现在考虑一个更复杂的例子,使用内部具有相同功能的特性:

trait Print {
type Input: ?Sized;
fn print(input: &Self::Input);
}
impl Print for f64 {
type Input = dyn Display;

// actually the same function as before
fn print(input: &dyn Display) {
println!("{}", input);
}
}

现在,如果我修改第一个函数如下:

fn print(input: &dyn Display) {
f64::print(input);
}

我得到了编译错误:

error[E0759]: `input` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement

为什么会发生这种情况?在特质的相关类型中,我看不出'static寿命要求的理由。

这里的例子。

是的,当dyn _类型用作关联类型时,它隐式地接收'static的生存期绑定。这是为了防止出现以下情况:

pub trait Stew {
type Item: ?Sized;
fn stew(&mut self, item: Box<Self::Item>);
}
use std::fmt::Display;
pub struct DisplayStew(Vec<Box<dyn Display>>);
impl Stew for DisplayStew {
type Item = dyn Display;
fn stew(&mut self, item: Box<Self::Item>) {
self.0.push(item);
}
}
impl DisplayStew {
pub fn new() -> Self {
DisplayStew(Vec::new())
}
pub fn look(&self) {
for item in &self.0 {
println!("- {}", item);
}
}
}
fn main() {
let mut bowl = DisplayStew::new();
bowl.stew(Box::new(123.456));
bowl.stew(Box::new("abcdef"));
{ // 'a begins
let s = "foo".to_owned();
bowl.stew(Box::new(&s)); // Box<&'a str>
} // 'a expires
// s was borrowed by bowl, but has ceased to exist, what now?
bowl.look();
}

如果没有生存期参数,编译器就无法限制一个类型对其关联类型的引用可以保留多长时间。

在稳定的Rust(1.58.1(上,目前还没有办法解决这个问题,但以下版本适用于不稳定的:

#![feature(generic_associated_types)]
use std::fmt::Display;
trait Print {
type Input<'a>: ?Sized;
fn print<'a>(input: &'a Self::Input<'a>);
}
impl Print for f64 {
type Input<'a> = dyn Display + 'a;
fn print<'a>(input: &'a (dyn Display + 'a)) {
println!("{}", input);
}
}
fn print(input: &dyn Display) {
println!("{}", input);
f64::print(input);
}
fn main() {
print(&123.);
}

相关内容

最新更新