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

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

问题描述

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

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

为什么会这样?这似乎是一个非常重大的疏忽.我的意思是,即使是 C/C++ 也更明确地使用两个 const 来表示我们有一个 const 指向 const 数据的指针:

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

有没有更好的思考方式?

解决方案

可变性是 Rust 中绑定的一个属性,而不是类型的一个属性.>

一个值的唯一所有者总是可以通过将它移动到一个可变绑定来改变它:

let s = "Hi".to_owned();//创建一个拥有的值.s.push('!');//错误,因为 s 是不可变的.让 mut t = s;//将拥有的值移动到可变绑定.t.push('!');//现在我们可以修改字符串了.

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

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

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

一旦你完成了一个值的改变,将一个值重新绑定为不可变是一种常见的模式:

让 mut x = ...;//修改 x ...让 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天全站免登陆