Scala:为什么必须使用def代替泛型而不是var

时间:2017-02-20 17:12:26

标签: scala

我有这个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
}

请为我解释一下。

3 个答案:

答案 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)

你的假设是错误的。使用valvar将无误编译。

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
}