简单问题:我在Scala中继承了一个FilterInputStream,它有一个read方法:
public void read(byte [] b,int offset,int len)
正在读取的数据将被放入b中,但由于参数在Scala方法中是“vals”,我认为无法正确地对其进行子类化。如何将b设置为正在读取的数据? Java * InputStream真的让我没有多少选择....
答案 0 :(得分:8)
您只需执行b
即可将项目放入i
索引b(i) = whatever
。 b
是val
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
时,您正在为同一事件制作b
和a
名称(不是副本,即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
仍然是可变的,您可以修改其内容。