Параметры изменяемого метода в Scala - PullRequest
1 голос
/ 17 октября 2010

Простая проблема: я подклассифицирую FilterInputStream в Scala, который имеет метод чтения:

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

Считываемые данные будут помещены в b, но, поскольку в методах Scala параметры являются "vals", я не вижу способа должным образом подклассировать это. Как установить b для считываемых данных? Java * InputStream действительно не оставляет мне большого выбора ....

Ответы [ 3 ]

8 голосов
/ 17 октября 2010

Вы можете поместить элемент в b по индексу i, просто набрав b(i) = whatever.То, что b является val, не влияет на это.Это просто означает, что вы не можете переназначить b (что в любом случае было бы бесполезно).

6 голосов
/ 18 октября 2010

Простое объявление чего-либо как val вместо var в Scala не делает его неизменным. Фактически, var может назвать неизменное значение. Следует помнить, что переменные в Scala, как и переменные в Java, всегда * ссылаются на или обрабатывают, а не содержат значение.

Попробуйте это в своем 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, это то, что вы не можете изменить имя экземпляра 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 ...). Это не так уж много, так как эти классы / типы в любом случае неизменны.

5 голосов
/ 17 октября 2010
def read(b: Array[Byte], offset: Int, len: Int): Unit

эквивалентно следующему в Java:

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

Массив b все еще изменчив, и вы можете изменять его содержимое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...