Rust 有没有一种方法可以省略这个特征的寿命?

Rust 有没有一种方法可以省略这个特征的寿命?,rust,lifetime,Rust,Lifetime,我又在和生命搏斗了。或者事实上,我赢得了这场战斗,但我不确定结果是否是预期的处理方式 假设我有一个具有两个生命周期的结构:internal。现在,我想编写一个trait来定义一个new(internal:&internal)->Self方法。实现者应该可以自由地在内部存储对internal的引用,并定义处理该引用的其他方法 我想到了这个(它是有效的!),但我有几个问题 struct Inner<'a, 'b>{ foo: &'a str, bar: &

我又在和生命搏斗了。或者事实上,我赢得了这场战斗,但我不确定结果是否是预期的处理方式

假设我有一个具有两个生命周期的结构:
internal
。现在,我想编写一个trait来定义一个
new(internal:&internal)->Self
方法。实现者应该可以自由地在内部存储对
internal
的引用,并定义处理该引用的其他方法

我想到了这个(它是有效的!),但我有几个问题

struct Inner<'a, 'b>{
    foo: &'a str,
    bar: &'b str
}

trait Worker<'data, 'a, 'b> {
    fn new (inner: &'data Inner<'a, 'b>) -> Self;
    fn work_with_inner () { println!("works on inner");}
}

struct SomeWorker<'inner, 'a:'inner, 'b:'inner> {
    inner: &'inner Inner<'a, 'b>
}

impl<'data, 'a, 'b> Worker<'data, 'a, 'b> for SomeWorker<'data, 'a, 'b> {
    fn new (inner: &'data Inner<'a, 'b>) -> Self {
        SomeWorker {
            inner: inner
        }
    }
}

fn main () {
}
游戏围栏:


这就是为什么我要问自己,作为trait的作者,我是否应该假设所有引用的方法最终都会被trait实现者存储在一个字段中,因此我需要指定trait上的所有生命周期,以便实现者能够做到这一点。

没有一刀切的解决方案。作为一个特质作者,你必须思考你正在尝试做什么,你想要实现什么

如果您希望能够将生命周期值与结构的生命周期参数关联起来,那么必须将生命周期放在trait上。通常会这样做,因为您的trait有多个方法可以在生命周期内对同一个值进行操作。这可能有点像getter/setter对。在我编写的一些代码中,我传递了
&str
引用,这些引用在“完成”它们之前保留了一段时间。如果您出于任何原因需要存储引用,那么您需要在trait上有生命周期

在您的例子中,您有一个构造函数方法,它需要知道结构是否存在生命周期。你可以将这一功能与其他特征区分开来,如果它确实不同的话。在您的示例中,
work\u with_internal
方法不接受
self
参数,因此这将是非常不同的。如果您使用了
self
,但不需要与
internal
中的生命周期交互,它仍然可以帮助您:

trait WorkerBuilder<'a, 'b> {
    fn new(inner: Inner<'a, 'b>) -> Self;
}

trait Worker {
    fn do_work(&self);
}

#[derive(Debug)]
struct Inner<'a, 'b>{
    foo: &'a str,
    bar: &'b str,
}

// This does track `Inner`
#[derive(Debug)]
struct SomeWorker<'a, 'b>(Inner<'a, 'b>);

impl<'a, 'b> WorkerBuilder<'a, 'b> for SomeWorker<'a, 'b> {
    fn new(inner: Inner<'a, 'b>) -> SomeWorker<'a, 'b> {
        SomeWorker(inner)
    }
}

impl<'a, 'b> Worker for SomeWorker<'a, 'b> {
    fn do_work(&self) { println!("Doing work, {:?}", self.0) }
}

// This doesn't track `Inner`
#[derive(Debug)]
struct DumbWorker;

impl<'a, 'b> WorkerBuilder<'a, 'b> for DumbWorker {
    fn new(inner: Inner<'a, 'b>) -> DumbWorker {
        DumbWorker
    }
}

fn main () {}
trait WorkerBuilder{
fn新(内部:内部)->自我;
}
特质工作者{
fn工作和自我;
}
#[导出(调试)]
结构内部{
富:和'阿街,
酒吧:&'b街,
}
//这不跟踪“内部”`
#[导出(调试)]
结构SomeWorker(内部);
为某个工人安装WorkerBuilder{
fn新(内部:内部)->SomeWorker{
工作人员(内部)
}
}
为某个工人导入工人{
fn do_work(&self){println!(“Doing work,{:?},self.0)}
}
//这不跟踪“内部”`
#[导出(调试)]
结构哑巴工人;
哑巴工人的impl WorkerBuilder{
fn新(内部:内部)->DumbWorker{
哑巴
}
}
fn main(){}
你会发现我还应用了一件你可以做的事情来减少生命周期。如果您的结构只是引用(或引用和其他小型
Copy
类型),则无需向该结构传递引用。引用是可复制的,跟踪包含结构的生存期是没有用的



编辑-我不觉得“构造函数”方法在一个特性中通常是有用的。您通常希望提供不同的集合或参数,这就是为什么您首先要使用不同的类型。也许您真正的代码在trait中使用的不是构造函数。

答案很好!缺少的
&self
是一个草率的例子。这让我想到了另一个问题哈哈
trait WorkerBuilder<'a, 'b> {
    fn new(inner: Inner<'a, 'b>) -> Self;
}

trait Worker {
    fn do_work(&self);
}

#[derive(Debug)]
struct Inner<'a, 'b>{
    foo: &'a str,
    bar: &'b str,
}

// This does track `Inner`
#[derive(Debug)]
struct SomeWorker<'a, 'b>(Inner<'a, 'b>);

impl<'a, 'b> WorkerBuilder<'a, 'b> for SomeWorker<'a, 'b> {
    fn new(inner: Inner<'a, 'b>) -> SomeWorker<'a, 'b> {
        SomeWorker(inner)
    }
}

impl<'a, 'b> Worker for SomeWorker<'a, 'b> {
    fn do_work(&self) { println!("Doing work, {:?}", self.0) }
}

// This doesn't track `Inner`
#[derive(Debug)]
struct DumbWorker;

impl<'a, 'b> WorkerBuilder<'a, 'b> for DumbWorker {
    fn new(inner: Inner<'a, 'b>) -> DumbWorker {
        DumbWorker
    }
}

fn main () {}