2015-07-23 18 views
8

Nếu tôi có các cấu trúc sau:Làm cách nào để hủy cấu trúc một bộ tuple để các liên kết có thể thay đổi được?

struct MyStruct { tuple: (i32, i32) }; 

Và các chức năng sau:

// This will not compile 
fn function(my_struct: &mut MyStruct) { 
    let (val1, val2) = my_struct.tuple; 
    val1 = 1; 
    val2 = 2; 
} 

Làm thế nào để mượn VAL1 và VAL2 như có thể thay đổi vì vậy khi tôi phân công lại họ những thay đổi xuất hiện trong cấu trúc ban đầu?

Trả lời

9

Bạn có một vài vấn đề:

  • Bạn đã đặt &mut ở địa điểm sai; &mut là một phần của loại, không phải là đối số (trừ khi bạn đang hủy hoại đối số, mà bạn không phải là đối số).

  • Bạn không thể gọi đối số struct, bởi vì đó là từ khóa.

  • Bạn không thể chỉ định cho tham chiếu có thể thay đổi được bằng chỉ định thẳng.

Như vậy, với những ý nghĩ đó, đây là một giải pháp làm việc:

#[derive(Debug)] 
struct MyStruct { 
    tuple: (i32, i32), 
} 

fn function(s: &mut MyStruct) { 
    let (ref mut val1, ref mut val2) = s.tuple; 
    *val1 = 1; 
    *val2 = 2; 
} 

fn main() { 
    let mut s = MyStruct { tuple: (0, 0) }; 
    function(&mut s); 
    println!("{:?}", s); 
} 

Mấu chốt ở đây là ref trong một mô hình liên kết bằng cách tham chiếu; kết hợp điều đó với mut cung cấp cho bạn một tham chiếu có thể thay đổi. Cụ thể, nó cung cấp cho bạn một cặp &mut i32 s. Vì đây là các tham chiếu, bạn phải bỏ tham chiếu chúng để gán thông qua chúng (nếu không, bạn sẽ cố gắng chỉ định lại tham chiếu).

8

Bạn có hai câu hỏi hơi khác nhau.

Bạn có thể tạo một ràng buộc có thể thay đổi bằng cách nói mut hai lần:

fn main() { 
    let a = (1, 2); 
    let (mut b, mut c) = a; 
    b += 1; 
    c += 2; 

    println!("{}, {}", b, c); 
} 

Nhưng để có nó thay đổi trong tuple gốc, bạn cần một có thể thay đổi tài liệu tham khảo vào tuple rằng:

fn main() { 
    let mut a = (1, 2); 

    { 
     let (ref mut b, ref mut c) = a; 
     *b += 1; 
     *c += 2; 
     // Let mutable borrows end 
    } 

    println!("{:?}", a); 
} 
Các vấn đề liên quan