web-dev-qa-db-fra.com

Quelle est la différence entre placer "mut" avant un nom de variable et après le ":"?

Voici deux signatures de fonction que j'ai vues dans la documentation Rust:

fn modify_foo(mut foo: Box<i32>) { *foo += 1; *foo }
fn modify_foo(foo: &mut i32) { *foo += 1; *foo }

Pourquoi le placement différent de mut?

Il semble que la première fonction pourrait également être déclarée comme

fn modify_foo(foo: mut Box<i32>) { /* ... */ }
60
Jimmy Lu

mut foo: T signifie que vous avez une variable appelée foo qui est un T. Vous êtes autorisé à modifier ce que la variable fait référence à:

let mut val1 = 2;
val1 = 3; // OK

let val2 = 2;
val2 = 3; // error: re-assignment of immutable variable

Cela vous permet également de modifier les champs d'une structure que vous possédez:

struct Monster { health: u8 }

let mut orc = Monster { health: 93 };
orc.health -= 54;

let goblin = Monster { health: 28 };
goblin.health += 10; // error: cannot assign to immutable field

foo: &mut T signifie que vous avez une variable qui fait référence à (&) une valeur et vous êtes autorisé à modifier (mut) valeur référencée (y compris les champs, s'il s'agit d'une structure):

let val1 = &mut 2;
*val1 = 3; // OK

let val2 = &2;
*val2 = 3; // error: cannot assign to immutable borrowed content

Notez que &mut n'a de sens qu'avec une référence - foo: mut T n'est pas une syntaxe valide. Vous pouvez également combiner les deux qualificatifs (let mut a: &mut T), quand cela a du sens.

55
Shepmaster

Si vous venez de C/C++, il pourrait également être utile de penser à cela essentiellement comme ceci:

// Rust          C/C++
    a: &T     == const T* const a; // can't mutate either
mut a: &T     == const T* a;       // can't mutate what is pointed to
    a: &mut T == T* const a;       // can't mutate pointer
mut a: &mut T == T* a;             // can mutate both

Vous remarquerez que ce sont des inverses les uns des autres. C/C++ adopte une approche de "liste noire", où si vous voulez que quelque chose soit immuable, vous devez le dire explicitement, tandis que Rust adopte une approche de "liste blanche", où si vous voulez que quelque chose soit mutable, vous devez le dire explicitement.

57
anderspitman