簡體   English   中英

什么是何時使用Scala的forSome關鍵字?

[英]What is and when to use Scala's forSome keyword?

List[T] forSome {type T}List[T forSome {type T}]什么List[T forSome {type T}] 我如何用“英語”閱讀它們? 我應該如何神交 forSome關鍵字? forSome一些實際用途是forSome 什么是有用的實用和復雜的簡單T forSome {type T}用法?

這里有很多問題,其中大部分已經在上面評論中鏈接的答案中得到了相當徹底的解決,所以我會回答你更具體的第一個問題。

List[T] forSome { type T }List[T forSome { type T }]之間沒有真正有意義的區別,但我們可以看到以下兩種類型之間的區別:

class Foo[A]

type Outer = List[Foo[T]] forSome { type T }
type Inner = List[Foo[T] forSome { type T }]

我們可以將第一個讀作“ T的foos列表,對於某些類型T ”。 整個列表中只有一個T 第二,在另一方面,可以理解為“FOOS的列表,其中每個foo是的T一些T ”。

換句話說,如果我們有一個outer: Outer列表outer: Outer ,我們可以說“存在一些類型T ,使得outerT的foos列表”,其中對於Inner類型的列表,我們只能說“對於列表的每個元素,存在一些T ,使得該元素是T的foo”。 后者較弱 - 它告訴我們較少的清單。

因此,例如,如果我們有以下兩個列表:

val inner: Inner = List(new Foo[Char], new Foo[Int])
val outer: Outer = List(new Foo[Char], new Foo[Int])

第一個將編譯得很好 - 列表中的每個元素對於某些T來說都是Foo[T] 第二個不會編譯,因為沒有一些T這樣列表中的每個元素都是Foo[T]

注意:( 更新2016-12-08 )根據Martin Odersky關於ScalaX 2016的討論,forSome關鍵字很可能會與Scala 2.13或2.14一起消失。用路徑依賴類型或匿名類型屬性替換它( A[_] )。 在大多數情況下這是可能的。 如果您的邊緣情況不可能,請重構您的代碼或放寬您的類型限制。

如何閱讀“forSome”(以非正式的方式)

通常當您使用通用API時,API會保證您可以使用您提供的任何類型(最多一些給定的約束)。 因此,當您使用List[T] ,List API會保證它可以與提供的任何類型T 使用

對於forSome (所謂的存在量化類型參數),它是相反的。 API將提供一種類型(不是你),它保證你,它將使用它提供給你的這種類型。 語義是,具體對象會給你一些類型為T東西。 同一個對象也會接受它為您提供的內容。 但沒有其他對象可以使用這些T s,沒有其他對象可以為您提供T類型的東西。

“存在量化”的概念是:存在(至少)一種類型T (在實現中)以履行API的合同。 但我不會告訴你它是哪種類型。

forSome可以讀取類似:對於某些類型的T的API合同成立。 但對於所有類型的T都不一定如此。 因此,當您提供某種類型的T (而不是在API的實現中隱藏的類型)時,編譯器無法保證您獲得了正確的T 所以它會拋出一個類型錯誤。

適用於您的示例

因此,當您在API中看到List[T] forSome {type T}時,您可以這樣閱讀:API將為您提供一些未知類型TList 它很樂意接受這個列表,它將與它一起使用。 但它不會告訴你, T是什么。 但至少你知道,列表中的所有元素都是相同的類型T

第二個有點棘手。 API再次為您提供一個List 它會使用某種類型的T而不是告訴你T是什么。 但是可以自由地為每個元素選擇不同的類型。 真實世界的API會為T建立一些約束,因此它實際上可以使用列表的元素。

結論

當您編寫API時, forSome很有用,其中每個對象代表API的實現。 每個實現都將為您提供一些對象,並將接受這些對象。 但是你既不能混合不同實現的對象,也不能自己創建對象。 相反,您必須始終使用相應的API函數來獲取可與該API一起使用的一些對象。 forSome可以實現非常嚴格的封裝。 您可以閱讀forSome通過以下方式:

對於某些類型,API合約折疊為true。 但你不知道它適用於哪種類型。 因此,您無法提供自己的類型,也無法創建自己的對象。 您必須使用通過使用forSome的API提供的那些。

這非常非正式,在某些極端情況下甚至可能是錯誤的。 但它應該幫助你理解這個概念。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM