Rod*_*una 7 mutable traits rust trait-objects
首先,我不是问&mut
和ref mut
本身有什么区别.
我在问,因为我想:
let ref mut a = MyStruct
Run Code Online (Sandbox Code Playgroud)
是相同的
let a = &mut MyStruct
Run Code Online (Sandbox Code Playgroud)
考虑从函数返回特征对象.你可以退还一个Box<Trait>
或一个&Trait
.如果您希望对其方法进行可变访问,是否可以返回&mut Trait
?
鉴于这个例子:
trait Hello {
fn hello(&mut self);
}
struct English;
struct Spanish;
impl Hello for English {
fn hello(&mut self) {
println!("Hello!");
}
}
impl Hello for Spanish {
fn hello(&mut self) {
println!("Hola!");
}
}
Run Code Online (Sandbox Code Playgroud)
该方法接收可变参考用于演示目的.
这不会编译:
fn make_hello<'a>() -> &'a mut Hello {
&mut English
}
Run Code Online (Sandbox Code Playgroud)
也不是这样
fn make_hello<'a>() -> &'a mut Hello {
let b = &mut English;
b
}
Run Code Online (Sandbox Code Playgroud)
但这将编译和工作:
fn make_hello<'a>() -> &'a mut Hello {
let ref mut b = English;
b
}
Run Code Online (Sandbox Code Playgroud)
我的理论
这个例子将开箱即用,带有不可变引用(不需要将它分配给变量,只返回&English
),但不能使用可变引用.我认为这是因为规则只能有一个可变引用或者你想要的不可变引用.
在不可变引用的情况下,您正在创建一个对象并将其作为返回表达式借用; 它的参考不会因为被借用而死亡.
在可变引用的情况下,如果您尝试创建一个对象并将其作为返回表达式可变地借用,则您有两个可变引用(创建的对象及其可变引用).由于您不能对同一个对象进行两次可变引用,因此它不会执行第二次,因此该变量的生存时间不够长.我认为当你编写let mut ref b = English
并返回时,b
你正在移动可变参考,因为它是由模式捕获的.
以上所有都是一个不好的尝试向我自己解释它为什么有效,但我没有基本的证据来证明它.
为什么会这样?
这是一个错误。我下面的原始分析完全忽略了它返回可变引用的事实。有关晋升的内容只有在价值观不变的情况下才有意义。
这是允许的,因为管理临时人员的规则存在细微差别(重点是我的):
在大多数左值上下文中使用右值时,如果未提升
'static
为 ,则会创建并使用临时的未命名左值。
参考文献继续:
当表达式
'static
可以用常量、借用和取消引用借用表达式最初写入的位置而不改变运行时行为时,就会将右值表达式提升到槽。也就是说,提升的表达式可以在编译时求值,并且结果值不包含内部可变性或析构函数(这些属性是根据可能的值确定的,例如&None
始终具有类型&'static Option<_>
,因为它不包含任何不允许的内容)。
您的第三个案例可以重写为“证明”促销'static
正在发生:
fn make_hello_3<'a>() -> &'a mut Hello {
let ref mut b = English;
let c: &'static mut Hello = b;
c
}
Run Code Online (Sandbox Code Playgroud)
至于为什么ref mut
允许或&mut
不允许这样做,我最好的猜测是,'static
促销是在尽最大努力的基础上进行的,&mut
只是没有被任何支票所捕获。您可能可以查找或提交描述情况的问题。
归档时间: |
|
查看次数: |
520 次 |
最近记录: |