2016-08-05 20 views
5

Tôi viết một hàm cho một cấu trúc, trong đó có một Vec nơi tôi cố gắng để lặp qua Vec:Iterating thông qua một Vec trong một struct - không thể di chuyển ra khỏi nội dung mượn

struct Object { 
    pub v: Vec<f32>, 
} 

impl Object { 
    pub fn sum(&self) -> f32 { 
     let mut sum = 0.0; 
     for e in self.v { 
      sum += e 
     } 
     sum 
    } 
} 

Tuy nhiên tôi nhận được như sau lỗi:

error: cannot move out of borrowed content [E0507] 
     for e in self.v { 
       ^~~~ 
help: run `rustc --explain E0507` to see a detailed explanation 

sự hiểu biết của tôi là kể từ self được mượn và rằng cho vòng lặp đang cố gắng để di chuyển các yếu tố của v ra e?

Từ mã lỗi, tôi đọc rằng giải pháp tiềm năng là sở hữu nhưng tôi không chắc chắn cách thực hiện điều đó.

Tôi không cố gắng sửa đổi véc tơ hoặc các phần tử của véc tơ. Tôi chỉ muốn sử dụng các yếu tố để chạy một số tính toán.

+0

Bạn đã xem ~ 70 [** câu hỏi khác có cùng thông báo lỗi **] (http://stackoverflow.com/search?q=%5Brust%5D+cannot+move + out + of + mượn + nội dung + là% 3Aq)? – Shepmaster

Trả lời

13

Đường: for e in self.v về bản chất là nói for e in (*self).v; bạn đang cố gắng lặp qua vectơ bằng cách di chuyển, gọi đặc điểm IntoIter của nó. Điều này sẽ phá hủy hoàn toàn vectơ, di chuyển tất cả các con số ra khỏi nó mãi mãi, không chỉ là những gì bạn muốn, mà còn không được phép trong bối cảnh này bởi vì bạn chỉ được phép đọc nó.

Bạn thực sự muốn lặp lại qua tham chiếu. Có hai cách để làm điều này:

for e in &self.v { 
    //... 
} 

này về cơ bản đang nói &((*self).v), kể từ khi . tự động dereferences bạn cần phải nói với trình biên dịch mà bạn thực sự chỉ muốn mượn vector.

hoặc

for e in self.v.iter() { 

} 

này có thể trông buồn cười bởi vì iter mất một &self. Tại sao? Vâng, trình biên dịch cũng tự động tham chiếu nếu bạn gọi hàm trên giá trị tham chiếu. Đây là bản chất (&((*self).v)).iter(), nhưng điều đó sẽ hút để viết để trình biên dịch giúp đỡ.

Vậy tại sao nó không tự động tham chiếu trong vòng lặp for? Vâng, for x in self.v là một tuyên bố hợp lệ và đó có thể là những gì bạn định viết. Nó thường là quan trọng hơn cho trình biên dịch để cho bạn biết rằng những gì bạn muốn muốn là không thể hơn giả sử bạn muốn cái gì khác. Với tham chiếu tự động (de-) ở trên, không có sự mơ hồ nào tồn tại.

Giải pháp cũ được ưu tiên, nhưng giải pháp sau là cần thiết nếu bạn muốn sử dụng bộ điều hợp lặp.

Phát biểu trong số đó, sum của bạn đã tồn tại hàng đêm. Chỉ cần viết self.v.iter().sum(). Nếu không, bạn có thể sử dụng self.v.iter().fold(0.0, |(acc, &v)| acc + v)

+0

Tuyệt vời, nó hoạt động hoàn hảo. Cám ơn rất nhiều. Vì vậy, điều này có nghĩa rằng bất cứ khi nào cuộc gọi 'self.struct_member' trình biên dịch gỉ xem nó như là' (* self) .struct_member' và di chuyển ra khỏi cấu trúc? Hoặc là đặc biệt cho 'cho x trong self.v' xây dựng – illeyezur

+0

@illeyezur Đó là những gì luôn luôn xảy ra (ngoại trừ các loại' Copy', nhưng đó là vì 'Copy' loại không di chuyển nói chung). – LinearZoetrope

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