Scala中的可变方法参数

时间:2010-10-17 17:06:17

标签: scala parameters mutable

简单问题:我在Scala中继承了一个FilterInputStream,它有一个read方法:

public void read(byte [] b,int offset,int len)

正在读取的数据将被放入b中,但由于参数在Scala方法中是“vals”,我认为无法正确地对其进行子类化。如何将b设置为正在读取的数据? Java * InputStream真的让我没有多少选择....

3 个答案:

答案 0 :(得分:8)

您只需执行b即可将项目放入i索引b(i) = whateverbval b对此没有影响。这只是意味着你无法重新分配{{1}}(这无论如何都无用)。

答案 1 :(得分:6)

在Scala中仅仅声明val而不是var并不能使其成为不可变的。实际上,var可以命名一个不可变的值。要记住的是,Scala中的变量(与Java中的变量非常相似)总是* references或句柄,而不是实际包含值。

在你的REPL中试试这个:

class Container { var content: String = "default" }
val a = new Container
val b = a
b.content = "modified"
println(a.content)

当您运行val b = a时,您正在为同一事件制作ba名称(不是副本,即Container的完全相同的实例)。因此,当您运行b.content = "modified"时,更改也会反映在a中;它只是同一件事的另一个名字。请注意,即使a是val,也会发生这种情况。所有val意味着您无法更改实例a的名称。

现在想想这个微小的变化:

class Container { var content: String = "default" }
def update(c: Container) { c.content = "modified" }
val a = new Container
update(a)
println(a.content)

当您致电update时,其参数c 也是 a的参考或别名。因此,更改会在方法调用之外反映出来,就像它们在前面的示例中一样。

数组是可变的,所以它们也是这样的。

*:原始变量(字节,双精度,整数等)不是Java中的引用;他们的盒装等价物(java.lang.Byte ...)是。它没有显示那么多,因为无论如何这些类/类型都是不可变的。

答案 2 :(得分:5)

def read(b: Array[Byte], offset: Int, len: Int): Unit

等同于以下Java:

public void read(final byte[] b, final int offset, final int len)

数组b仍然是可变的,您可以修改其内容。