< 返回版块

Simon 发表于 2024-06-17 10:12

参考 https://rust-lang.github.io/generic-associated-types-initiative/explainer/iterable.html

实现了 iterable, 在 iterable 基础上,有一个trait 返回 一个 iterable 对象就编译不过去了。


Ext Link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7bd77f0b0d655f24b31d131065431d79

评论区

写评论
Neutron3529 2024-06-17 15:06
trait TestTrait {
    type Collection<'c>: for<'i> Iterable<Item<'i> = Self::Item<'i>> + 'c
        where Self: 'c;

    // type Collection<'c>: Iterable<Item<'c> = Self::Item<'c>> + 'c
    //     where Self: 'c;

    type Item<'c>: std::fmt::Display where Self: 'c;

    fn collection<'c>(&'c self) -> Self::Collection<'c>;
}

这个trait的定义有问题

假设你对Foo定义了TestTrait,然后你执行

let a=Foo::new();
let a=Foo::new().collection();
let mut b=Foo::new();
let c=b.collection();
drop(c);
/*让我们看看执行到这里的时候会发生什么*/

首先,let a=Foo::new().collection();请求了一个生命周期为'c的借用

然后,后面的let c=b.collection();同样请求了一个生命周期为'c的借用

现在,我们drop掉一个借用。

正常观点是,b的不可变借用已经被drop了,所以接下来我们可以放心地修改b的取值

然而还有另一个观点:对b的借用需要持续'c这么久,而目前'c还没有结束(因为a的借用生命周期也是同样的'c

于是现在不能修改b

——如此看,你对TestTrait的定义其实是不合理的。你或许应该转而定义TestTrait<'c>才对

SleepyBoy 2024-06-17 14:37

TestTrait::Collection的生命周期标注'i'c是两个不同的生命周期,并且没有关联约束,所以impl里会报错。 但是我改了一下后,traverse函数里又不对了。。

let iter = collection.get_iter(); ^^^^^^^^^^ borrowed value does not live long enough

后面这个没搞懂,有点懵

1 共 2 条评论, 1 页