所以我现在正在学习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)
}
Run Code Online (Sandbox Code Playgroud)
问题是我一直收到这个错误:
错误:类型不匹配;
发现:T
必需:String
def add(即: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, y, 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)
}
Run Code Online (Sandbox Code Playgroud)
让我解释.首先,T: Numeric是一个隐式为Numeric[T]您的类提供实例的上下文绑定.
该Numeric[T]特性提供了数字类型的操作,
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
}
Run Code Online (Sandbox Code Playgroud)
该表达式implicitly[Numeric[T]]检索此隐式上下文,以便您可以执行诸如plus具体参数x,y和z之类的操作,如上面的私有方法所示.
你现在可以构造和使用's和'的add不同实例:Vector3IntDouble
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)
Run Code Online (Sandbox Code Playgroud)
附注:可以使用隐式转换将值转换为Numeric[T].Ops实例,以便可以编写以下内容:
def add(that: Vector3[T]) = new Vector3(x + that.x, y + that.y, z + that.z)
Run Code Online (Sandbox Code Playgroud)
我故意选择不使用这些隐式转换,因为它们(可能)会通过创建临时包装器对象而导致性能损失.实际的性能影响取决于JVM(例如,它支持转义分析到何种程度以避免堆上的实际对象分配).使用上下文绑定并implicitly避免这种潜在的开销......以一些冗长为代价.
| 归档时间: |
|
| 查看次数: |
3925 次 |
| 最近记录: |