Movatterモバイル変換


[0]ホーム

URL:


codecamp

可变性

可变性

可变性,可以改变东西的能力,与其他语言相比它在 Rust 中有点不同。可变性的第一个方面是它的非默认状态:

let x = 5;x = 6; // error!

我们可以应用mut 关键字来介绍可变性:

let mut x = 5;x = 6; // no problem!

这是一个可变的变量绑定。当一个绑定是可变时,这意味着你可以更改绑定的指向。所以在上面的例子中,不是x 的值发生变化,而是这个绑定从i32 更改为其他。

如果你想要更改绑定的指向,你将需要一个可变的引用

let mut x = 5;let y = &mut x;

y 是一个绑定到一个可变引用的不可变值,这意味着你不可以将y 绑定到其他 (y = &mut z ),但是你可以改变绑定到y上的东西 ( *y=5 ).细微的差别。

当然,如果你两个都需要,可以如下书写:

let mut x = 5;let mut y = &mut x;

现在y 可以绑定到另一个值,并且这个引用的值可以改变。

注意到mut 是<模式的一部分是非常重要的,你可以这样编写代码:

let (mut x, y) = (5, 6);fn foo(mut x: i32) {

内部和外部可变性

然而,在 Rust 中当我们说有些东西是‘不变’的,这并不意味着它不可以更改:我们说的是它有‘外部可变性’。考虑如下例子,Arc<T>

use std::sync::Arc;let x = Arc::new(5);let y = x.clone();

当我们调用clone() 时,Arc<T> 需要更新引用计数。然而我们在这里还没有使用mutx 是一个不可变绑定,同时我们没有使用&mut 5 或者任何东西。所以谁给?

要理解这一点,我们需要回到 Rust 的指导哲学的核心,内存安全,和 Rust 保证的机制,所有权系统,和更具体的,借用

You may have one or the other of these two kinds of borrows, but not both at the same time:one or more references (&T) to a resource.exactly one mutable reference (&mut T)

所以,这就是‘不变’的真正定义:有两个指针指向内容是否安全?在Arc<T> 的例子中,是的:变化完全包含在内部结构本身中。它不是面向用户的。为此,将&T 传递给clone()。但是,如果将&mut T 传递给clone(),将会成为一个问题:

其它类型,诸如std::cell 模块中,具有相反的:内部可变性。例如:

use std::cell::RefCell;let x = RefCell::new(42);let y = x.borrow_mut();

RefCell 用borrow_mut() 函数来将&mut 引用传递到它包含的东西中。那样不危险吗?如果那样做会怎样:

use std::cell::RefCell;let x = RefCell::new(42);let y = x.borrow_mut();let z = x.borrow_mut();

事实上,这将在运行时引起恐慌。这是RefCell 做的事情:它在运行时保证 Rust 的借用规则,同时如果它们违背了规则时的panic!。这允许我们能够绕过 Rust 的不变规则的另一方面。让我们先讲讲吧。

字段级可变性

可变性是借用 (&mut ) 或者绑定 (let mut ) 的一个属性。这意味着,例如,你不能有一个结构体既有一些字段可变还有一些不可变:

struct Point {x: i32,mut y: i32, // nope}

一个结构体在绑定方面的可变性:

struct Point {x: i32,y: i32,}let mut a = Point { x: 5, y: 6 };a.x = 10;let b = Point { x: 5, y: 6};b.x = 10; // error: cannot assign to immutable field `b.x`

然而,通过使用Cell<T>,你可以模仿字段级可变性:

use std::cell::Cell;struct Point {x: i32,y: Cell<i32>,}let point = Point { x: 5, y: Cell::new(6) };point.y.set(7);println!("y: {:?}", point.y);

以上代码将打印y: Cell { value: 7 }。我们已经成功更新y

生存期
结构体
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录
关于
介绍

新手入门

学习 Rust

高效 Rust

语法和语义

Nightly Rust

词汇表
相关学术研究

关闭

MIP.setData({'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false},'pageFontSize' : getCookie('pageFontSize') || 20});MIP.watch('pageTheme', function(newValue){setCookie('pageTheme', JSON.stringify(newValue))});MIP.watch('pageFontSize', function(newValue){setCookie('pageFontSize', newValue)});function setCookie(name, value){var days = 1;var exp = new Date();exp.setTime(exp.getTime() + days*24*60*60*1000);document.cookie = name + '=' + value + ';expires=' + exp.toUTCString();}function getCookie(name){var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)');return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null;}
[8]ページ先頭

©2009-2025 Movatter.jp