2017-12-11 158 views
7

Tôi đọc các ấn bản thứ hai của Sách Rust và tôi thấy các mẫu sau trong phần lặp:Tại sao trình biên dịch không phàn nàn rằng một trình vòng lặp được chuyển đến vòng lặp for là không thay đổi?

let v1 = vec![1, 2, 3]; 
let v1_iter = v1.iter();  
for val in v1_iter { 
    println!("Got: {}", val); 
} 

Tại sao trình biên dịch không phàn nàn rằng v1_iter là bất biến? Cuốn sách cho biết vòng lặp for đã sở hữu v1_iter và làm cho nó có thể thay đổi đằng sau hậu trường, nhưng bạn có thể chuyển đổi biến không thay đổi thành có thể thay đổi được không?

Trả lời

9

Cuốn sách nói rằng vòng lặp for mất quyền sở hữu của v1_iter và làm cho nó có thể thay đổi đằng sau hậu trường,

Chính xác, và người ta có thể làm cho một ví dụ thậm chí đơn giản hơn:

let v = vec![1,2,3]; 
let mut x = v; 
x.push(0); 

Lưu ý rằng vx là các ràng buộc biến riêng biệt: miễn là biến v giữ lại vector 3 phần tử của chúng tôi, hợp đồng biến là vector sẽ không bị biến đổi. Tuy nhiên, vectơ đã được chuyển đến x, tuyên bố rằng khả năng đột biến là chấp nhận được. Điều tương tự cũng áp dụng cho các cuộc gọi chức năng:

fn foo(mut x: Vec<i32>) { 
    x.push(0); 
} 

let v = vec![1,2,3]; 
foo(v); 

Điều này là an toàn vì chỉ một trong các biến sở hữu véc tơ tại bất kỳ thời điểm nào trong vòng đời của nó. Sau khi v được chuyển đến x, v không thể sử dụng được nữa. Tương tự như vậy, trong mã của bạn, không thể sử dụng v1_iter sau vòng lặp for.

nhưng bạn có thể chuyển đổi biến không thay đổi thành có thể thay đổi không?

Cả hai đoạn mã đều hoạt động vì giá trị được chuyển sang biến mới được khai báo là mut. Tuy nhiên, khi một biến được khai báo là không thay đổi (hoặc có thể thay đổi), biến đó vẫn như vậy cho toàn bộ thời gian tồn tại của nó và không thể thay đổi. Vì vậy, câu trả lời là không, nhưng ngữ nghĩa quyền sở hữu cho phép di chuyển các giá trị trên các biến có bảo đảm đột biến khác nhau.

Các vấn đề liên quan