-mut -[T] 是什麼意思?

引用可能會讓人很困惑,特別是對於不同類型的可變性。事實上,在我的調查中,只有三分之一的人說他們明白 & mut &[T] 是什麼意思!

基本規則

在 Rust 中,要改變一個值,你需要對它有某種唯一的訪問權,例如,一個 & mut(對 T 的唯一可變引用)。另一方面,共享引用 (&T) 不能唯一訪問。

因爲共享引用沒有唯一訪問權,所以,如果你在一個類型中有一個共享引用,你不能通過它改變任何東西。

稍微簡單一點的問題:&mut &T 是什麼意思?

如果一個共享引用不允許你改變它之後的任何東西,因此 & mut &T 不允許你改變類型 T 的值。雖然你不能改變 T,但是你可以改變 T 的引用 & T:

let value = 1;
let mut shared: &u32 = &value;

println!("{r:p}: {r} (value = {v})"r = shared, v = value);
// Prints <addr>: 1 (value = 1)

let unique: &mut &u32 = &mut shared;
*unique = &17;

println!("{r:p}: {r} (value = {v})"r = shared, v = value);
// Prints <different addr>: 17 (value = 1)

切片有什麼不同?

使用 & mut &[T],你仍然可以更改引用,使其指向另一個切片。但是 &[T] 本質上是一個胖指針,這意味着它不僅是一個指針,而且還包含切片的長度。

既然你可以改變引用,做爲引用的一部分,存儲長度也可以改變:

let mut slice: &[u8] = &[0, 1, 2, 3, 4];
let unique: &mut &[u8] = &mut slice;

// Since we want to hold unique reference, 
// we can only access the slice through it
println!("({r:p}, {len}): {r:?}"r = *unique, len = unique.len());
// Prints (<addr>, 5)[0, 1, 2, 3, 4]

// Change only the length
*unique = &unique[..4];
println!("({r:p}, {len}): {r:?}"r = *unique, len = unique.len());
// Prints (<addr>, 4)[0, 1, 2, 3]

// Change both the pointer and the length
*unique = &unique[1..];
println!("({r:p}, {len}): {r:?}"r = *unique, len = unique.len());
// Prints (<addr+1>, 3)[1, 2, 3]

// Change only the pointer
*unique = &[17, 17, 42];
println!("({r:p}, {len}): {r:?}"r = *unique, len = unique.len());
// Prints (<different addr>, 3)[17, 17, 42]

一個真實的例子是 io::Read 爲 &[u8] 實現了 & mut &[T]:

use std::io::Read;

// We'll be reading *from* this slice
let mut data: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// And *into* this
let mut buf = [0; 3];

while let Ok(1..) = Read::read(&mut data, &mut buf) {
    println!("({r:p}, {len}): {r:?}", r = data, len = data.len());
    // This will print:
    // (<addr>, 7): [3, 4, 5, 6, 7, 8, 9]
    // (<addr+3>, 4): [6, 7, 8, 9]
    // (<addr+6>, 1): [9]
    // (<addr+7>, 0): []   

    // In reality you'd also examine the `buf` contents here
}

現在你知道 & mut &[T] 的意思了吧!我希望這對你有幫助。

本文翻譯自:

https://ihatereality.space/04-what-mutref-to-slice-ref-means/

coding 到燈火闌珊 專注於技術分享,包括 Rust、Golang、分佈式架構、雲原生等。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/81OrjiXYmg6g3axjgalsHg