2017-11-18 64 views
1

我剛纔瞭解到,使用泛型的結構聲明爲struct Foo<T>,並且實現聲明爲impl<T> Foo<T>。該book解釋下列方式的差異:有沒有技術上的原因爲什麼實施不只是impl Foo <T>?

注意到,我們才能在類型Point<T>使用T只是impl後申報T。在impl之後聲明T爲普通類型是Rust如何知道Point中的尖括號中的類型是泛型類型而不是具體類型。

再次,我是一個新手,也沒有同樣的論點具有申報struct<T> Foo<T>(甚至可能fn<T> foo<T>(bar: T))進行?

+1

通過[Rust By Example](https://rustbyexample.com/generics/impl.html),我猜這是因爲'impl Foo '已經意味着別的東西:「將Foo泛型類型實現爲一個特定類型,稱爲T「。 – millimoose

+1

想象相反的情況:不'IMPL富'的意思是「爲32位整數實現的Foo」或「通用實現美孚的一個'i32'任何類型的參數」?您提到的其他情況中沒有這種含糊之處。 – millimoose

+0

@millimoose:所以在某些情況下,''''表示泛型,並且在某種特定類型中?看起來很難知道我在處理哪一個而不熟悉語法。 – l0b0

回答

7
impl Foo<T> { ... } 

T一個類型參數,或命名T一個實際的類型?如果您回答了第二個問題,那麼您已經將泛型拋出窗口:完全不可能爲一組通用類型實現功能。如果您的回答第一個,那麼你怎麼建議用戶這樣做:

impl Foo<T> { /* generic stuff */ } 
impl Foo<i32> { /* i32-specific stuff */ } 
impl Foo<u32> { /* u32-specific stuff */ } 

這隻會是三個impl塊,分別命名爲Ti32u32類型參數。

你可能會說「很好,只是從上下文決定」。現在,爲了弄清楚發生了什麼,用戶不僅要檢查模塊的其餘部分,還要檢查標準庫的前奏中的所有導入符號以確定類型是否爲參數。 Rust憎惡這種含糊之處。

遠,更簡單的編譯器和讀者只是具體什麼是和不是一個參數。

您不必這樣做與struct,因爲括號內的東西不可能是任何東西其他比類型參數聲明。

+0

謝謝,這澄清了它。我想我的困惑源於含糊不清,有時*''是指通用的,有時是特定的類型。 – l0b0

1

除了@dk的回答,我想比較一下Rust如何對Haskell做它。

在Haskell中,所有特定類型必須啓動大寫。因此,它是非法的寫:

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

相反,哈斯克爾保留其用小寫字母開頭的類型變量類型:

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

相關問題