scala – 在通配符上键入Boundary“Stickyness”
我在
scala论坛上遇到了这个
post.
这是一个回顾:
scala> class Foo { def foo = 42 } defined class Foo scala> class Bar[A <: Foo](val a: A) defined class Bar scala> def bar(x: Bar[_]) = x.a.foo :7: error: value foo is not a member of Any
然后讨论进入Spec解释争议:) 说明? 最后海报提出了这样的解释:
我不明白,因为 def bar[A](x: Bar[A]) 因为Bar类型参数是有界的,所以不会单独编译. 无论如何,我相信以下将是完全有道理的: def bar(x: Bar[_],y : Bob[_]) 解决方法 作为一种解决方法,他们建议: def bar(x: Bar[_ <: Foo]) = x.a.foo 除了不干燥之外,它会让事情变得困难: 让我们考虑一棵树 abstract class Tree[T <: Tree[T]] { val subTree : List[T] } 现在,您将如何定义递归遍历树的函数(显然在Tree类之外定义): def size( tree : Tree[_] ) = tree.subTree.size + tree.subTree.map(size(_)).sum 显然不会工作,因为subTree将变成List [Any],所以我们需要一个类型参数: def size[T <: Tree[T]]( tree : T ) = ... 甚至更丑陋: class OwnATree( val myTree : Tree[_] ){} 应该成为 class OwnATree[T <: Tree[T]]( val myTree : T ){} 等等…… 我相信某处出了点问题:) 解决方法
使用大小和OwnATree完成所需的最简单方法是使用存在类型:
def size(tree: Tree[T] forSome { type T <: Tree[T] }): Int = tree.subTree.size + tree.subTree.map(size(_)).sum 和: class OwnATree(val myTree: Tree[T] forSome { type T <: Tree[T] }) 你的Tree [_]版本实际上也在使用存在类型 – 它们只是包含在一些语法糖中.换一种说法, def size(tree: Tree[_]): Int = ... 只是语法糖: def size(tree: Tree[T] forSome { type T }): Int = ... 你不能将你需要的约束添加到下划线版本,但你可以添加到desberared版本. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |