加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么ListNode示例(Scala网站)可以处理不同的类型?

发布时间:2020-12-16 09:49:45 所属栏目:安全 来源:网络整理
导读:从 Scalas主页获取的 ListNode example是这样的: case class ListNode[+T](h: T,t: ListNode[T]) { def head: T = h def tail: ListNode[T] = t def prepend[U : T](elem: U): ListNode[U] = ListNode(elem,this)} 通过这个类,我们可以创建如下对象: val e
从 Scalas主页获取的 ListNode example是这样的:

case class ListNode[+T](h: T,t: ListNode[T]) {
  def head: T = h
  def tail: ListNode[T] = t
  def prepend[U >: T](elem: U): ListNode[U] =
    ListNode(elem,this)
}

通过这个类,我们可以创建如下对象:

val empty: ListNode[Null] = ListNode(null,null)
val strList: ListNode[String] = empty.prepend("hello")
                                     .prepend("world")
val anyList: ListNode[Any] = strList.prepend(12345)

我们可以看到,我们可以在String节点前加一个整数值.我想,这是有效的,因为当给定前置方法的整数时,类型参数U将自动设置为Any(因为Int不是String的超类型).

使用自己的下限示例尝试此操作时,我将收到错误:

scala> class E[T >: String]
defined class E

scala> new E[Any]
res1: E[Any] = E@135f0a

scala> new E[Int]
<console>:11: error: type arguments [Int] do not conform to class E's type param
eter bounds [T >: String]
      val res2 =
          ^
<console>:12: error: type arguments [Int] do not conform to class E's type param
eter bounds [T >: String]
              new E[Int]
                  ^

为什么Int类型不会像ListNode示例中那样自动被视为类型Any?

更新1:这也有效(没有说明新的ListNode应该是Any类型)

scala> val empty: ListNode[Null] = ListNode(null,null)
empty: example.listNode.ListNode[Null] = ListNode(null,null)

scala> empty.prepend("hello").prepend("world")
res0: example.listNode.ListNode[java.lang.String] = ListNode(world,ListNode(hell
o,ListNode(null,null)))

scala> val strList: ListNode[String] = empty.prepend("hello").prepend("world")
strList: example.listNode.ListNode[String] = ListNode(world,ListNode(hello,ListN
ode(null,null)))

scala> strList.prepend(12345)
res1: example.listNode.ListNode[Any] = ListNode(12345,ListNode(world,ListNode(he
llo,null))))

解决方法

您得到上述错误,因为Int不是String的超类型.

请注意,在上面的ListNode代码中,String是Null的超类型(参见class hierarchy),而Any是String的超类型(正如您正确指出的那样).

我猜想混淆是由比较两个不完全相同的操作引起的:new E [Int]使用类型参数Int实例化类,这不符合下限String,因此失败.

另一方面,您调用prepend方法,该方法采用超类型U的T.当创建anyList时,U(正如您猜测的那样)解析为Any,因为这是String和Int的唯一常见超类型,所以你可以认为它并没有真正传递一个Int,而只是一些Any的任意实例(也恰好是Int类型).

因此,

val anyList: ListNode[Int] = strList.prepend(12345)

也失败了,因为strList.prepend(12345)只能返回ListNode [Any].

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读