2010-10-17 2 views
1

Простой задача: Я подклассы в FilterInputStream в Scala, который имеет метод чтения:Изменяемые параметры метода в Scala

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

считываемые данные будут введены в б, но, как параметры «Vals» в Scala, я не вижу возможности правильно подклассифицировать это. Как установить b на считываемые данные? Java * InputStream действительно оставляет мне не большой выбор ....

ответ

8

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

+0

Спасибо, все. Я считал массив неизменным, чего не должно быть. Забавно, что я никогда не сталкивался с этим до сих пор (большая часть моего кода - чистая Scala, а затем вы используете разные шаблоны - по крайней мере, я :-) – Maarten

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

является equivanet к следующему в Java:

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

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

+2

Иногда мне интересно, где @missingfaktor находит время, чтобы быть повсюду :-) –

+2

@ olle kullberg Думаю, это команда разработчиков, работающих под одним аккаунтом :) –

6

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

Попробуйте это в РЕПЛ:

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

При запуске val b = a вы делаете b и a имена для одного и того же (не копия, точно такой же экземпляр контейнера). Из-за этого при запуске 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. Таким образом, изменения отражаются вне вызова метода так же, как и в предыдущем примере.

Массивы изменяемы, поэтому они работают так же.

*: Примитивные переменные (байты, двойники, int и т. Д.) Не являются ссылками в Java; их эквиваленты в штучной упаковке (java.lang.Byte ...). Это не показывает многого, так как эти классы/типы в любом случае неизменны.

Смежные вопросы