Cell 因为内部可变性,会让Cell 相对于T 不变。 为什么似乎在下面的函数中,并不会严格两个函数参数的lifetime完全匹配。 https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=701b7efc3ed036db2147cfd74bb480cc
fn retsct3<'a>(to_drop: &'a String, rg: Cell<&'a i32>)
{
;
}
函数签名中使用同一lifetime标注,并且其中一个是Cell中,传参过程中Cell<&'a i32> 相对于&'a i32 不变。传递的是Cell<&'static i32>,那就要求 函数中'a 是 'static 。而第一个参数的lifetime 只能在那个局部scope 内,这样不就冲突了吗?
1
共 11 条评论, 1 页
评论区
写评论我最后总结一下吧。
生命周期描述了什么
以
'c
标记成编译通过的生命周期参数:let cell: Cell<&'c str> = Cell::new(refincell);
那么 f 的签名
fn f<'c>(s: &'c str, cell: &Cell<&'c str>) { }
表示: 只要保持传入给 f 的 s 有效,那么Cell<&'c str>
就能有效地存在;一旦 s 所引用的数据被销毁,则不得再使用 cell;否则导致编译错误。variance 发挥的作用
因为 Cell 对 'c 是 invariant,这意味着传递给 cell 这个参数的生命周期时,'c 应保持不变。
但这不会阻止对其他参数发生隐式的型变转换:
&
对 'c 是 covariant,所以对于给定的 'c,任何传递给 s 参数的引用可以至少比 'c 长。我的例子中, 'static: 'c、'string: 'c、's: 'c 都满足这些时,代码才能通过。是。。。。。。。。。。
--
👇
leolee0101: 是不是 应该是
&'_ i32
短于等于 ss ?是不是 应该是
&'_ i32
短于等于 ss ?--
👇
苦瓜小仔: 我的表述还存在一点问题。
sc 的类型是一个被推断的更短的生命周期的
Cell<&'_ i32>
,但&'_ i32
一定比 ss 要长(而不是我之前说的,与变量 ss 生命周期相同)。更准确地说,
Cell<&'_ i32>
中的&'_ i32
的确是(因为 invariance)固定的,但当前 Rust 借用规则 NLL 实质上是围绕生命周期的约束集合求解。具体的逻辑推断,我帮你在官方论坛提问了,@Steffahn 大佬回答得很详尽。 https://users.rust-lang.org/t/help-me-to-understand-invariance-and-lifetime-here
感谢苦瓜小仔仔~~
我也有很多东西不知道,不是大佬 :)
回答问题也是一种学习。相互学习~
哇,中外大佬们的热情和精力,让人钦佩。苦瓜大佬是专职rust相关的(维护中文社区?之类)吗,感觉精力特别棒,回答提问都特别详细认真。跟以前知乎里编译原理虚拟机领域里的 FX 一样。五体佩服。
--
👇
苦瓜小仔: 我的表述还存在一点问题。
sc 的类型是一个被推断的更短的生命周期的
Cell<&'_ i32>
,但&'_ i32
一定比 ss 要长(而不是我之前说的,与变量 ss 生命周期相同)。更准确地说,
Cell<&'_ i32>
中的&'_ i32
的确是(因为 invariance)固定的,但当前 Rust 借用规则 NLL 实质上是围绕生命周期的约束集合求解。具体的逻辑推断,我帮你在官方论坛提问了,@Steffahn 大佬回答得很详尽。 https://users.rust-lang.org/t/help-me-to-understand-invariance-and-lifetime-here
我的表述还存在一点问题。
sc 的类型是一个被推断的更短的生命周期的
Cell<&'_ i32>
,但&'_ i32
一定比 ss 要长(而不是我之前说的,与变量 ss 生命周期相同)。更准确地说,
Cell<&'_ i32>
中的&'_ i32
的确是(因为 invariance)固定的,但当前 Rust 借用规则 NLL 实质上是围绕生命周期的约束集合求解。具体的逻辑推断,我帮你在官方论坛提问了,@Steffahn 大佬回答得很详尽。 https://users.rust-lang.org/t/help-me-to-understand-invariance-and-lifetime-here
感谢。有了这么详细的解答,才明白。属实有点愚钝了。确实是没注意到sc 类型推断的地方。
--
👇
苦瓜小仔: > 传递的是Cell<&'static i32>,那就要求 函数中'a 是 'static
这句话是对的。在你的例子中,标注
let sc: Cell<&'static i32> = Cell::new( refincell);
就可以印证:所以 sc (在声明时)的类型(就已经)不是
Cell<&'static i32>
,而是一个(根据 retsct3 的Cell<&'a i32>
推断出的)更短生命周期的Cell<&'ss i32>
(与变量 ss 生命周期相同)。你只关注到了
Cell<&'a i32>
是 invariant,但没关注到&'lifetime T
是 covariant。感谢,新手,一时间没点透。看了 苦瓜兄 的解答,才明白您说的是哪个地方。惭愧。
--
👇
7sDream: 因为
&'a T
对于'a
是协变的。这句话是对的。在你的例子中,标注
let sc: Cell<&'static i32> = Cell::new( refincell);
就可以印证:所以 sc (在声明时)的类型(就已经)不是
Cell<&'static i32>
,而是一个(根据 retsct3 的Cell<&'a i32>
推断出的)更短生命周期的Cell<&'ss i32>
(与变量 ss 生命周期相同)。你只关注到了
Cell<&'a i32>
是 invariant,但没关注到&'lifetime T
是 covariant。因为
&'a T
对于'a
是协变的。