2017-01-06 3 views
7

は、Index traitが定義されている:`Index`特性の` Idx`型のパラメータはなぜunsizeされていますか?次のように錆1.14で

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

Outputタイプの束縛暗黙のSizedはここ?Sizedと緩和されています。これは意味があります。index()メソッドはOutputへの参照を返します。したがって、unsized型を使うことができます。これは便利です。例:

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

Idxタイプパラメータの暗黙的な境界も緩和され、サイズを変更できます。しかし、Idxはメソッドの引数として値によって使用され、引数としてunsized型を使用することはAFAIKでは不可能です。 Idxはサイズを変更できますか?

答えて

6

私はこれが歴史の事故であると確信しています。その緩い縛りはwas introduced in 2014に縛られます。この時点で、Indexタイプが参照によってを通過したことを

// 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; 
} 

注:その時、形質は、異なるビットを見ました。その後renamed Idx type changed to pass by value上:

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

はしかし、両方形式が異なるコンパイラのブートストラップ段階的に共存していることに注意してください。これはおそらく、オプションのSizedバインドをすぐに削除できなかった理由です。それは私の推測それは基本的により重要な変更のために忘れられていた、そして今私達はどこにいるのです。

それは(?Sized除去することで)バウンドが何かを壊す制限するかどうかを判断するための興味深い思考実験だ...多分誰かが上...^_^

思考実験をPRを提出しなければなりません! Lukas submitted a PR!それはのようなIndexのsubtraitsを作成し、下流のコードを壊す可能性がある議論が行われています:

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

ありまたそのいつかの話だ、私は理解していないが、我々は、値によって動的サイズの種類(DSTS)を渡したいかもしれませんどうやって。

+3

いつものようにすばらしい答え! – mcarton

+2

*いつかは、動的サイズの型(DST)を値で渡すこともできますが、私は理解できません。* =>言語と実装には違いがあります。言語が移動(値渡し)を考慮しているということは、ABIレベルでは値がポインタによって渡されないことを意味するものではありません。したがって、実際の実装ではポインターが使用されているため、言語がDSTに値を渡すことは完全に賢明です。しかし、価値によってそれらを返すことは、よりトリッキーなようです:) –

関連する問題