2017-01-06 16 views
7

Trong Rust 1,14, các Index trait được định nghĩa như sau:Tại sao tham số loại `Idx` của đặc điểm` Chỉ số` được phép được unsized?

pub trait Index<Idx> where Idx: ?Sized { 
    type Output: ?Sized; 
    fn index(&self, index: Idx) -> &Self::Output; 
} 

Các ngầm Sized ràng buộc của các loại Output là thoải mái với ?Sized đây. Điều này có ý nghĩa, bởi vì phương pháp index() trả về một tham chiếu đến Output. Do đó, các loại chưa được sử dụng có thể được sử dụng, điều này rất hữu ích; ví dụ:

impl<T> Index<Range<usize>> for Vec<T> { 
    type Output = [T]; // unsized! 
    fn index(&self, index: Range<usize>) -> &[T] { … } // no problem: &[T] is sized! 
} 

Ràng buộc tiềm ẩn của thông số loại Idx cũng thoải mái và có thể được unsized. Nhưng Idx được sử dụng bởi giá trị làm đối số phương thức và sử dụng các loại chưa được đánh số làm đối số là không thể AFAIK. Tại sao Idx được phép để được unsized?

Trả lời

6

Tôi chắc chắn đây chỉ là một sự cố về lịch sử. Người khai thác đó bị ràng buộc was introduced in 2014. Tại thời điểm đó, đặc điểm nhìn một chút khác nhau:

// Syntax predates Rust 1.0! 
pub trait Index<Sized? Index, Sized? Result> for Sized? { 
    /// The method for the indexing (`Foo[Bar]`) operation 
    fn index<'a>(&'a self, index: &Index) -> &'a Result; 
} 

Lưu ý rằng vào thời điểm này trong thời gian, loại Index đã được thông qua bằng cách tham khảo. Sau đó các renamed Idx type changed to pass by value:

fn index<'a>(&'a self, index: Idx) -> &'a Self::Output; 

Tuy nhiên, lưu ý rằng cả dạng cùng tồn tại trong giai đoạn biên dịch bootstrap khác nhau. Đó có thể là lý do tại sao không thể xóa ngay ràng buộc Sized tùy chọn. Đó là tôi đoán rằng về cơ bản nó đã bị lãng quên do những thay đổi quan trọng hơn, và bây giờ chúng tôi là nơi chúng tôi đang có.

Đây là một thí nghiệm tưởng tượng thú vị để quyết định nếu hạn chế ràng buộc (bằng cách loại bỏ ?Sized) sẽ phá vỡ bất cứ điều gì ... có lẽ ai đó nên nộp một PR ...^_^nghiệm

tưởng hơn! Lukas submitted a PR! Đã có thảo luận rằng nó có thể phá vỡ mã hạ lưu tạo subtraits của Index như:

use std::ops::Index; 
trait SubIndex<I: ?Sized>: Index<I> { } 

Ngoài ra còn có nói chuyện một ngày nào đó, chúng ta có thể chuyển các loại động cỡ (DSTs) theo giá trị, mặc dù tôi không hiểu làm sao.

+3

Câu trả lời hay như bình thường! – mcarton

+2

* Cũng có nói rằng một ngày nào đó, chúng ta có thể muốn truyền các loại có kích thước động (DST) theo giá trị, mặc dù tôi không hiểu làm thế nào. * => Có sự khác biệt giữa ngôn ngữ và triển khai. Chỉ vì ngôn ngữ xem xét nó là một động thái (đi qua giá trị) không ngụ ý rằng ở mức ABI giá trị không được chuyển bởi con trỏ. Và do đó nó là hoàn toàn hợp lý để có ngôn ngữ vượt qua DST bởi các giá trị với việc thực hiện thực tế là một con trỏ được sử dụng. Trả lại chúng theo giá trị, tuy nhiên, có vẻ phức tạp hơn :) –

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