2017-01-22 16 views
19

Với mã này:Tại sao liên kết `T: 'a` bắt buộc để lưu trữ tham chiếu` &' a T`?

struct RefWrapper<'a, T> { 
    r: &'a T, 
} 

... trình biên dịch phàn nàn:

error: the parameter type T may not live long enough

consider adding an explicit lifetime bound T: 'a so that the reference type &'a T does not outlive the data it points at.

Tôi đã nhìn thấy lỗi này nhiều lần rồi và cho đến nay tôi chỉ nghe trình biên dịch và tất cả mọi thứ đã làm việc ra tốt đẹp . Tuy nhiên, suy nghĩ thêm về nó, tôi không hiểu lý do tại sao Tôi phải viết T: 'a.

Theo như tôi hiểu, đó là đã không thể có được tham chiếu như vậy. Có &'a T ngụ ý rằng có một đối tượng thuộc loại T sống ít nhất 'a. Nhưng chúng tôi không thể lưu trữ bất kỳ tài liệu tham khảo nào trong đối tượng đã nói đến dữ liệu có tuổi thọ ngắn hơn 'a. Điều này sẽ đã dẫn đến lỗi trình biên dịch.

Trong ý nghĩa đó, bạn không thể nhận được số &'a T trong đó T không vượt quá 'a. Do đó, chú thích bổ sung (T: 'a) không cần thiết.

Tôi có đúng không? Tôi có sai và nếu có: làm thế nào tôi có thể phá vỡ mã, nếu T: 'a sẽ không được yêu cầu?


Links:

+1

tôi đã hỏi #rust và có vẻ như [mã này] (https: // github.com/rust-lang/rust/issues/24622 # issuecomment-94761287) sẽ phá vỡ mọi thứ, nếu yêu cầu 'T: 'a' được dỡ bỏ. Nhưng tôi chưa thực sự hiểu mã đó và tôi sẽ ngừng thử ngay bây giờ. Hy vọng rằng ai đó hiểu được câu trả lời trong thời gian chờ đợi^_^ –

+0

[RFC liên quan từ tháng 8 năm 2017] (https://github.com/rust-lang/rfcs/pull/2093) –

Trả lời

15

Đây là một phần của quy tắc nổi formedness. Kiểu &'a T chỉ được định dạng tốt nếu T: 'a (“T outlives 'a”; nó là bắt buộc vì chúng tôi có tham chiếu mà chúng tôi có thể truy cập trong phạm vi 'a; giá trị được chỉ định trong T cần phải hợp lệ cho ít nhất là phạm vi, quá).

struct RefWrapper<'a, T> là loại chung và nó cho biết bạn có thể nhập một đời 'x và loại U và nhận lại loại RefWrapper<'x, U>. Tuy nhiên, loại này không nhất thiết phải được hình thành tốt hoặc thậm chí được triển khai trừ khi yêu cầu T: 'a được tôn trọng.

Yêu cầu này đến từ chi tiết triển khai; nó không nhất thiết để T'a được sử dụng cùng nhau như &'a T trong nội bộ của cấu trúc. Yêu cầu về tính hình thành tốt cần được đẩy mạnh lên giao diện công khai của cấu trúc RefWrapper, để các yêu cầu hình thành loại RefWrapper<'_, _> là công khai, ngay cả khi việc triển khai nội bộ không được thực hiện.

(Có những nơi khác, nơi mà cùng một yêu cầu T: 'a trở lại nhưng là implict:

pub fn foo<'a, T>(x: &'a T) { } 

chúng tôi nhận ra một sự khác biệt:. Đây loại &'a T là một phần của api công cộng, quá)

+0

Điều đó có ý nghĩa, cảm ơn bạn <3 –

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