我有这个scala代码:
trait Monoid[A] {
def op(a1: A, a2: A): A
def zero: A
}
val stringMonoid = new Monoid[String] {
override def op(a1: String, a2: String): String = a1 + a2
override def zero: String = ""
}
def listMonoid[A] = new Monoid[List[A]] {
override def op(a1: List[A], a2: List[A]): List[A] = a1 ++ a2
override def zero: List[A] = Nil
}
我的问题是,如果我在这种情况下从def
更改为val
,则Scala将无法编译:
var listMonoid[A] = new Monoid[List[A]] {
override def op(a1: List[A], a2: List[A]): List[A] = a1 ++ a2
override def zero: List[A] = Nil
}
请为我解释一下。
答案 0 :(得分:1)
var
存储对某个对象的引用(或者某个原始值,以便完成)。拥有,例如</ p>是没有意义的
var list[A] = mutable.ListBuffer.empty[A]
因为它可以让您同时将列表的同一实例视为不同类型的列表。如下例所示:
val listInt = list[Int]
listInt += 42
val listString = list[String]
val str: String = listString.head // world implodes
答案 1 :(得分:1)
问题在于listMonoid方法是用类型A进行参数化的,这是不可能用var或val做的,你不能实现一个对类型通用的对象,你需要指定什么A是
var listMonoid = new Monoid[List[Any]] {
override def op(a1: List[Any], a2: List[Any]): List[Any] = a1 ++ a2
override def zero: List[Any] = Nil
}
答案 2 :(得分:0)
你的假设是错误的。使用val
或var
将无误编译。
trait Monoid[A] {
val op: (A, A) => A
var zero: A
}
def listMonoid[A] = new Monoid[List[A]] {
override val op = (a1: List[A], a2: List[A]) => a1 ++ a2
override var zero: List[A] = Nil
}