[英]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]
這是, A
是Int
。 現在我們打電話
t.test("foo")
"foo"
的類型為String
,但字符串是Any
子類型,因此可以這樣考慮,因此可以調用test[B >: A](b : B)
其中b
為"foo"
, B
為Any
。
下面的例子應該說明這一點,考慮一下
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
,而是最不常見的A
和B
超類型。 對於Int
和String
這恰好是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.