2017-11-18 10 views
1

私は、ジェネリックスを使用する構造体がstruct Foo<T>と宣言され、実装がimpl<T> Foo<T>と宣言されたことを知りました。私たちはタイプPoint<T>Tを使用するためには、単にimplTを宣言する必要が実装が単にimpl Foo <T>ではないという技術的な理由はありますか?

注:bookは、以下の方法で矛盾を説明しています。 implの後にTをジェネリック型として宣言するには、Pointの山括弧の型をRustが具体的な型ではなくジェネリック型であると知っている必要があります。

は再び、私は初心者だけど、同じ引数を(おそらく、さらにはfn<T> foo<T>(bar: T)struct<T> Foo<T>を宣言したために作らことができませんでしたか?

+1

[ust by Example](https://rustbyexample.com/generics/impl.html)で行くと、 'impl Foo 'はすでに何かを意味していると思います。「1つのFooジェネリック型を実装するT "と呼ばれる特定のタイプのものである。 – millimoose

+1

逆の状況を想像してみましょう: 'impl Foo 'は「32ビット整数のFooの実装」または「i32'という名前の型パラメータのFooの汎用実装」を意味しますか?このあいまいさは、他の場合には言及していません。 – millimoose

+0

@millimoose:したがって、いくつかのケースでは、<>は一般的なものであり、特定のタイプのものもありますか?構文に慣れていないと、どちらが私が扱っているのかを知ることは難しいようです。 – l0b0

答えて

7
impl Foo<T> { ... } 

型パラメータ、またはTという名前の実際の型Tですか? 2番目に答えた場合は、ジェネリックをウィンドウ全体にスローしました。一般的なタイプのセットの機能を実装することは不可能です。あなたが最初に答えた場合、どのようにユーザーがこれを行う提案ん:

ちょうどそれぞれ3つの impl Tという名前の型パラメータを持つブロック、 i32、および u32だろう
impl Foo<T> { /* generic stuff */ } 
impl Foo<i32> { /* i32-specific stuff */ } 
impl Foo<u32> { /* u32-specific stuff */ } 

"よく、文脈から決めてください"と言うかもしれません。ここで何が起こっているのかを調べるには、モジュールの残りの部分だけでなく、インポートされたすべての記号が、型がパラメータであるかどうかを判断するための標準ライブラリのプレリュードのものをチェックする必要があります。錆はこの種のあいまいさを嫌う。

far、farコンパイラと読者はパラメータが何であるかどうかを特定するだけで簡単です。

角括弧の中にあるものは、型パラメータ宣言よりも以外のなので、structとする必要はありません。

+0

ありがとう、これはそれを明確にします。私の混乱は、時には「」という曖昧さから生まれたものだと思います。 – l0b0

1

@dkの答えに加えて、私はハスケルがそれをどうやってそれを行うのかを比較したいと思います。

ハスケルでは、すべての特定のタイプを大文字で開始する必要があります。

data mytype Var = Constructor { 
    myVar :: Var, 
    myInt :: Foo 
} 

その代わり、Haskellは型変数のために、小文字文字で始まるタイプの留保:したがって、それは書くことは違法である。ここ

data MyType var = Constructor { 
    myVar :: var 
    myInt :: Int 
} 

instance MyClass (MyType var) where 
    ... 

を、varは型変数があり、MyTypeコンクリートであります、Intが具体的です。

あなたが共有しないかもしれない私の意見では、Rustは大文字でないタイプ識別子を許可する間違いを犯しました。したがって、言語には他に選択肢がありませんが、どのタイプ識別子が変数で、どの識別子が特定であるかを明示的に要求する必要があります。 Rustの説明が読みやすさを向上させる議論がなされる可能性がある。反対も議論することができます。

サビはもちろん、あなたが言うかもしれない仮想的な機能追加することができます。ここでは

impl Foo<#T, T, u32> { .. } 

を、接頭辞#は、「これは型変数である」を意味すると解釈するので、#Tは型変数で、Tがあるさ特異的であり、u32が特異的である。あいまいさはなく、ローカル推論だけが必要です。

この機能を使用すると、多少の冗長さを感じるかもしれませんが、私はこの船が航行したと確信しています。この機能を追加することで、同じことを少しでも増やすことができます。しかし、この機能は、言語ユーザーが学ばなければならない別の機能を持つコストを追加します。

+1

偉大な比較と問題の要約! – l0b0

関連する問題