2015-07-20 63 views
0

那爲什麼是這樣的:需要幫助瞭解斯卡拉list.contains如何工作

val map = Map(....) 

List(1,2,3,4).contains(map) 

List(1,2,3,4).contains("hello") 

是否允許進行編譯。我雖然斯卡拉是安全的。

+1

這已被問:[http://stackoverflow.com/questions/31466497/why-does-scala-listint-contains-accept-optionint] 對於類型安全性,我們可以使用類型約束'x.contains [ Int](4)'或使用'x.exists(_ == 4)'。 – jwvh

回答

0

如果我們諮詢scaladocs for List.contains,你會發現下面的方法簽名:

def contains[A1 >: A](elem: A1): Boolean

特別感興趣的是類型參數,[A1 >: A]如果我們打破這種下來,我們得到:

  • A,列表包含的元素的類型
  • A1,元素的類型耳鼻喉科您在列表中
  • >:搜索,代表符號的下界

這應該被解釋爲A1是一個下界,所以A1是兩種類型的A或更通用的類型。有關更低類型邊界的更多信息,請參見http://www.scala-lang.org/old/node/137

你有一個列表Int。您詢問列表是否包含String。由於Any >: StringAny >: Int,編譯器不會抱怨。 Map方案適用相同的情況。

+1

'String>:Int'不是true,因爲'String'不是'Int'的超類型。但是,任何'String'也是'Any',它是'Int'的超類型,所以編譯器推斷你的意思是調用'contains [Any]'。 (1).contains [String](「foo」)'將會失敗,但是'List(1).contains [Any](「foo」)將會失敗, )'會編譯。 –

+0

在這種情況下'A1:> A'有什麼好處?如果它沒有真正添加任何類型的安全性,是否包含[Any]完全相同的事情,或者是否存在其他支持的其他用例? – Ren

+0

@Ren它最終是因爲List在A中是協變的。完整的解釋是非常模糊的,但是如果你感興趣的類型和它爲什麼必須這樣,請檢查http://stackoverflow.com/a/2078619/ 2643828。 – Zeimyth