2017-02-20 45 views
1

我有这样的Scala代码:斯卡拉:为什么必须使用高清仿制的,而不是VAR

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,斯卡拉不会编译:

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

“val”用于常量值,“var”用于可变变量,“def”用于声明函数。 –

+0

在你的第二个例子中,你说过你使用'val',但我只看到一个'var'。 – Carcigenicate

+0

其他问题和答案对泛型没有提及,但是在这里被问到。 –

回答

1

A var存储对某个对象(或某个原始值,待完成)的引用。它没有意义的有,例如一个

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

的问题则存在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 
} 
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 
} 
+0

我认为问题不在于特征内部的签名,而是关于从def listMonoid [A]移动到var listMonoid [A] – Mikel

+0

@Mikel,你可能是对的。 OP的要求并不明显。这个问题应该以_unclear_结束。 – jwvh

相关问题