为什么变量的可变性未在Rust的类型签名中反映出来? [英] Why is the mutability of a variable not reflected in its type signature in Rust?

查看:84
本文介绍了为什么变量的可变性未在Rust的类型签名中反映出来?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,可变性未反映在变量类型签名中.例如,这两个引用具有相同的类型签名&i32:

 let ref_foo : &i32 = &foo;
let mut ref_bar : &i32 = &bar;
 

为什么会这样?似乎是一个相当大的疏忽.我的意思是,甚至C/C ++都使用两个const来更明确地做到这一点,以表明我们有一个指向const数据的const指针:

 const int * const ptr_foo = &foo;
const int * ptr_bar = &bar;
 

是否有更好的方法来考虑这一点?

解决方案

可变性是Rust中绑定的属性,而不是 type 的属性.

值的唯一所有者始终可以通过将其移动到可变绑定来对其进行突变:

let s = "Hi".to_owned();  // Create an owned value.
s.push('!');              // Error because s is immutable.
let mut t = s;            // Move owned value to mutable binding.
t.push('!');              // Now we can modify the string.

这表明可变性不是值类型的属性,而是它的绑定.当然,该代码仅在当前未借用该值的情况下才有效,这会阻止移动该值.共享借阅仍然保证是不变的.

引用的可变性与绑定的可变性正交. Rust使用相同的mut关键字来消除两种类型的引用的歧义,但这是一个独立的概念.

内部可变性模式再次与上述正交,因为它是该类型的一部分.包含CellRefCell或类似内容的类型可以修改,即使仅保留对它们的共享引用.

更改值后,将值重新绑定为不可变是一种常见的模式:

let mut x = ...;
// modify x ...
let x = x;

Rust中的所有权语义和类型系统与C ++有所不同,我更喜欢Rust方式.正如您所暗示的那样,我认为它本质上并没有那么表达.

As I understand, mutability is not reflected in variables type signature. For example, these two references have the same type signature &i32:

let ref_foo : &i32 = &foo;
let mut ref_bar : &i32 = &bar;

Why is this the case? It seems like a pretty major oversight. I mean, even C/C++ does this more explictly with having two const to indicate that we have a const pointer to const data:

const int * const ptr_foo = &foo;
const int * ptr_bar = &bar;

Is there a better way of thinking about this?

解决方案

Mutability is a property of a binding in Rust, not a property of the type.

The sole owner of a value can always mutate it by moving it to a mutable binding:

let s = "Hi".to_owned();  // Create an owned value.
s.push('!');              // Error because s is immutable.
let mut t = s;            // Move owned value to mutable binding.
t.push('!');              // Now we can modify the string.

This shows that mutability is not a property of the type of a value, but rather of its binding. The code of course only works if the value isn't currently borrowed, which would block moving the value. A shared borrow is still guaranteed to be immutable.

Mutability of references is orthogonal to mutability of bindings. Rust uses the same mut keyword to disambiguate the two types of references, but it's a separate concept.

The interior mutability pattern is again orthogonal to the above, as it is part of the type. Types containing a Cell, RefCell or similar can be modified even when only holding a shared reference to them.

It's a common pattern to rebind a value as immutable once you are done mutating a value:

let mut x = ...;
// modify x ...
let x = x;

Ownership semantics and the type system in Rust are somewhat different than C++, and I prefer the Rust way. I don't think it's inherently less expressive, as you seem to suggest.

这篇关于为什么变量的可变性未在Rust的类型签名中反映出来?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆