任何人都可以分享对scala中“不可变”特征的洞察力吗?乍一看,我认为这将是一个很好的控制结构来限制我正在构建的类,但奇怪的是我注意到原始类型不会扩展它。是否有一个原因?有没有办法将语法绑定到Immutable或AnyVal?
class Test {
def test[T<:Immutable](x:T)={
println("passes "+x)
}
case class X(s:String) extends Immutable
test(X("hello")) //passes
// test("fail") - does not pass compiler
}
答案 0 :(得分:2)
所谓的原始类型(Boolean,Byte,Char,Short,Int,Long,Float,Double)本质上是不可变的。 5是5是5.你不能做任何事情来把它变成任何不是5的东西。
否则,不变性是值存储方式的属性。如果存储在var
中,var
可以使用新值(兼容类型)自由替换。通过扩展,构造类型(class
es,trait
和object
s)可以是不可变的或可变的,这取决于它们是否允许在构造之后改变它们的任何内部状态。 / p>
Java的String
(也用作Scala的String
)是不可变的。
然而,这些都与你的例子没有任何关系,因为你没有证明可变性。您只是展示了将一个值的+
方法应用于另一个值时会发生什么。
虽然有可能实现一个+
方法来改变它的(明显的)左手操作数,但很少有人这样做。如果需要这种突变,那么通常会定义+=
方法。
+
有点特别之处在于,它可以应用于任何值(如果参数/右手操作数)是String
,因为隐式转换为定义{的特殊类{1}}以便可以应用+(s: String)
的字符串连接解释。换句话说,如果您编写+
并且表达式e1 + "e2"
的类型未定义e1
,则Scala会将+
转换为e1
并将其连接起来与String
。
答案 1 :(得分:2)
Scala核心库中Immutable
的唯一直接子类型是:
collection.immutable.Traversable
collection.parallel.immutable.ParIterable
根本没有其他任何内容引用Immutable
。
Immutable
hasn't been changed自2009年在Martin Odersky的“massive new collections checkin”中添加。我正在搜索该提交,看起来Immutable
在它首次引入时从未被用作绑定。
老实说,我怀疑这些特质背后有很多意图。 Odersky可能计划使用Immutable
绑定不可变集合上的类型参数,然后更好地考虑它。但那只是我的推测。