2014-09-21 28 views
18

Editor's note: This code no longer produces the same error after RFC 599 was implemented, but the concepts discussed in the answers are still valid.Tại sao "yêu cầu ràng buộc suốt đời rõ ràng" cho Hộp <T> trong cấu trúc?

Tôi đang cố gắng để biên dịch mã này:

trait A { 
    fn f(&self); 
} 

struct S { 
    a: Box<A>, 
} 

và tôi nhận được lỗi này:

a.rs:6:13: 6:14 error: explicit lifetime bound required 
a.rs:6  a: Box<A>, 

Tôi muốn S.a để sở hữu một thể hiện của A, và không xem cuộc đời đó phù hợp như thế nào ở đây. Tôi cần phải làm gì để làm cho trình biên dịch hài lòng?

Rust My phiên bản:

rustc --version 
rustc 0.12.0-pre-nightly (79a5448f4 2014-09-13 20:36:02 +0000) 

Trả lời

16

Vấn đề ở đây là một đặc điểm có thể được thực hiện để tham khảo quá, vì vậy nếu bạn không xác định thời gian tồn tại cần thiết cho Box bất cứ điều gì có thể được lưu trữ trong đó.

Bạn có thể xem các yêu cầu về tuổi thọ trong số rfc này.

Vì vậy, một giải pháp khả thi là để ràng buộc thời gian tồn tại rất Send (chúng tôi đặt tôi trong S):

trait A { 
    fn f(&self); 
} 

struct I; 

impl A for I { 
    fn f(&self) { 
     println!("A for I") 
    } 
} 

struct S { 
    a: Box<A + Send> 
} 

fn main() { 
    let s = S { 
     a: box I 
    }; 
    s.a.f(); 
} 

Các khác là thiết lập thời gian tồn tại để 'a (chúng ta có thể đặt một tài liệu tham khảo & I hoặc I S):

trait A { 
    fn f(&self); 
} 

struct I; 

impl A for I { 
    fn f(&self) { 
     println!("A for I") 
    } 
} 

impl <'a> A for &'a I { 
    fn f(&self) { 
     println!("A for &I") 
    } 
} 

struct S<'a> { 
    a: Box<A + 'a> 
} 

fn main() { 
    let s = S { 
     a: box &I 
    }; 
    s.a.f(); 
} 

lưu ý rằng đây là tổng quát hơn và chúng ta có thể lưu trữ tất cả tài liệu tham khảo và dữ liệu thuộc sở hữu (Send loại mà có một đời của 'static) nhưng bạn cần một parame đời ter ở khắp mọi nơi loại được sử dụng.

+0

Cảm ơn bạn đã liên kết RFC, nó làm sáng tỏ một số ánh sáng trong suốt thời gian tồn tại bên trong Hộp. –

18

(điểm Hơi pedantic: đó A là một đặc điểm, vì vậy S không được sở hữu một thể hiện của A, nó được sở hữu một thể hiện đóng hộp của một số loại mà thực hiện A.)

Một đối tượng đặc điểm đại diện cho dữ liệu với một số loại không xác định, đó là, điều duy nhất được biết về dữ liệu là nó thực hiện các đặc điểm A. Bởi vì loại không được biết, trình biên dịch không thể trực tiếp lý luận về tuổi thọ của dữ liệu chứa, và do đó yêu cầu thông tin này được khai báo rõ ràng trong kiểu đối tượng đặc điểm.

Điều này được thực hiện qua Trait+'lifetime. Phương pháp dễ nhất là chỉ cần sử dụng 'static, nghĩa là hoàn toàn không cho phép lưu trữ dữ liệu có thể trở thành vô hiệu do phạm vi:

a: Box<A + 'static> 

Trước đây, (trước khả năng đặc điểm đời-giáp đối tượng và thông điệp explicit lifetime bound required lỗi này đã được giới thiệu) tất cả các đối tượng đặc điểm đóng hộp là hoàn toàn 'static, nghĩa là, hình thức bị hạn chế này là lựa chọn duy nhất.

Các hình thức linh hoạt nhất được phơi bày cuộc đời bên ngoài:

struct S<'x> { 
    a: Box<A + 'x> 
} 

này cho phép S để lưu trữ một đối tượng đặc điểm của bất kỳ loại mà thực hiện A, có thể với một số hạn chế về phạm vi trong đó S là hợp lệ (tức là đối với các loại mà 'x nhỏ hơn 'static đối tượng S sẽ bị mắc kẹt trong một số khung ngăn xếp).

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