簡體   English   中英

理解斯卡拉的界限令人困惑

[英]confusion in understanding scala's bound

我正在閱讀Demystifying Scala Type System ,在第17張幻燈片中有一個片段:

class Test[+A] {
  def test[B >: A](b: B): String = b.toString
}

幻燈片說方法測試將接受A類或任何超類型的A.但似乎我可以通過任何類型進行測試。

vat t = new Test[Int]
t.test("foo")
t.test(List(1, 2, 3))

當我閱讀Scala編程時,我也有同樣的困惑。

這里要記住的重要一點是Any是任何類型的超類型,即

Any >: A

特別是假設

val t = new Test[Int]

這是, AInt 現在我們打電話

t.test("foo")

"foo"的類型為String ,但字符串是Any子類型,因此可以這樣考慮,因此可以調用test[B >: A](b : B)其中b"foo"BAny

下面的例子應該說明這一點,考慮一下

class Test[+A](a : A) {
  def test[B >: A](b : B) : (A,B) = (a,b)
}

現在,使用

val t = new Test(3)
val x = t.test("foo")

我們得到

x: (Int, Any) = (3,foo)

最后,為了添加一些細節,Scala不會總是選擇Any ,而是最不常見的AB超類型。 對於IntString這恰好是Any (參見http://www.scala-lang.org/old/node/128 ),但對於其他示例可能會有所不同,例如,

val s = new Test(Nil)
val y = s.test("foo")
val z = s.test(List(1))

我們將得到

y: (scala.collection.immutable.Nil.type, java.io.Serializable) = (List(),foo)
z: (scala.collection.immutable.Nil.type, List[Int]) = (List(),List(1))

另請注意,下限不會阻止傳遞A子類型

scala> val a = new Test(new AnyRef())
a: Test[java.lang.Object] = Test@6771a12

scala> a.test("foo")
res6: (java.lang.Object, java.lang.Object) = (java.lang.Object@78b99f12,foo)

所以,問題是,什么是低級類型邊界有用? 一個可能的答案是它們可以用於“控制”“輸出”位置的類型,通常用於協變類型參數,參見,例如, http//docs.scala-lang.org/tutorials/tour/lower -type-bounds.html粗略地說,當將一個元素附加到類型A的(協變)列表時,您希望確保結果列表至少是類型A (我很抱歉這部分內容很浪漫,但是因為它超出了原始問題的范圍,我只是想簡要介紹一下為什么需要它們,為了得到完整答案,最好創建它一個新問題)

由於Any,該參數可以接受任何類型。 但是,我不認為這個例子非常清楚。 如果您將此代碼段放入工作表中

如果定義了返回類型是與B相關的東西,您將看到問題

class Test[+A] {
  def test[B >: A](b: B): B = b
}


class A

class B extends A

val test = new Test[B]

val t = test.test("test")

返回類型不是String ,是Object 所以基本上,它失去了類型參考。

我們需要像這樣定義的原因是A是協變的 在這種情況下,由於Function1 [-A,+ B]的定義,它只能用於返回類型而不是參數 如果使用def測試(b:A).....它將有編譯錯誤:

協變類型A出現在價值b def測試的類型A的逆變位置(b:A):String = b.toString

此外,如果要約束超類型,可以有多個選項。 其中一個是使用隱式來約束類型。

class C

class CCC extends C

def test[B >: A](b: B)(implicit ev: B =:= C): B = b

val test = new Test[CCC]

test.test(new C)//ok

test.test("123")//compilation error

暫無
暫無

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

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