templates – 在Scala中键入参数化
所以我现在正在学习
Scala,我正在尝试创建一个矢量空间为3(x,y,z坐标)的抽象矢量类.我正在尝试使用以下代码添加其中两个向量:
package math class Vector3[T](ax:T,ay:T,az:T) { def x = ax def y = ay def z = az override def toString = "<"+x+","+y+","+z+">" def add(that: Vector3[T]) = new Vector3(x+that.x,y+that.y,z+that.z) } 问题是我一直收到这个错误:
我已经尝试过评论上面的“toString”方法,但这似乎没有任何影响.谁能告诉我我做错了什么? 解决方法
使用Scala 2.8,你可以写:
case class Vector3[T: Numeric](val x: T,val y: T,val z: T) { override def toString = "(%s,%s,%s)" format (x,z) def add(that: Vector3[T]) = new Vector3( plus(x,that.x),plus(y,that.y),plus(z,that.z) ) private def plus(x: T,y: T) = implicitly[Numeric[T]] plus (x,y) } 让我解释.首先,T:Numeric是一个上下文绑定,它隐式地为您的类提供Numeric [T]实例. Numeric [T] trait提供对数字类型的操作, trait Numeric[T] extends Ordering[T] { def plus(x: T,y: T): T def minus(x: T,y: T): T def times(x: T,y: T): T def negate(x: T): T // other operations omitted } 表达式隐式[Numeric [T]]检索此隐式上下文,以便您可以对具体参数x,y和z执行诸如加号之类的操作,如上面的私有方法所示. 您现在可以构造和添加Vector3的不同实例化,例如使用Int和Double: scala> Vector3(1,2,3) add Vector3(4,5,6) res1: Vector3[Int] = (5,7,9) scala> Vector3(1.1,2.2,3.3) add Vector3(4.4,5.5,6.6) res2: Vector3[Double] = (5.5,7.7,9.899999999999999) 附注:可以使用隐式转换将值转换为Numeric [T] .Ops实例,以便可以编写以下内容: def add(that: Vector3[T]) = new Vector3(x + that.x,y + that.y,z + that.z) 我故意选择不使用这些隐式转换,因为它们(可能)会通过创建临时包装器对象而导致性能损失.实际性能影响取决于JVM(例如,它支持转义分析到何种程度以避免堆上的实际对象分配).使用上下文绑定并隐含地避免了这种潜在的开销……以一些冗长的代价为代价. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |