我想创建一个方法求和,我可以调用不同的类型,特别是sum(1,2).
def sum[A](a1: A,a2: A) = a1 + a2
这失败是因为编译器无法判断A是否有方法”
我试图定义一个结构类型:
type Addable = {def(a:Addable)}
由于非法循环引用,这会失败
如何在不需要A扩展特定特征的情况下以类型安全的方式实现此目的?
解决方法
如果没有其他编译器参数(特别是-Yrecursion),Scala不支持递归类型别名.这部分是为了使类型检查器至少在某种程度上保持可判定性(但是,正如我们已经发现的那样,即使没有递归类型别名,类型系统也是Turing Complete,因此它并不重要).
执行此类操作的正确方法是使用类型类. Scala将这些编码为隐式视图边界.例如:
trait Addable[A] { def zero: A def add(x: A,y: A): A } implicit object IntAddable extends Addable[Int] { def zero = 0 def add(x: Int,y: Int) = x + y } implicit object DoubleAddable extends Addable[Double] { def zero = 0 def add(x: Double,y: Double) = x + y } // ... def sum[A](x: A,y: A)(implicit tc: Addable[A]) = tc.add(x,y)
当然,这也允许你做一些奇特的事情,比如以类型安全的方式对Seq的内容进行求和:
implicit def summableSeqSyntax[A](seq: Seq[A])(implicit tc: Addable[A]) = new { def sum = seq.foldLeft(tc.zero)(tc.add) } List(1,2,3,4).sum // => 10 List(true,false).sum // does not compile
值得注意的是,Scala 2.8与Numeric类型类非常接近.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。