繁体   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