В чем разница между определением var и val в Scala?
в чем разница между var
и val
определение в Scala и почему язык нуждается в обоих? Почему вы выбрали val
на var
и наоборот?
13 ответов
как говорили многие другие, объект, назначенный val
не может быть заменен, и объект, назначенный var
может. Однако указанный объект может иметь измененное внутреннее состояние. Например:
class A(n: Int) {
var value = n
}
class B(n: Int) {
val value = new A(n)
}
object Test {
def main(args: Array[String]) {
val x = new B(5)
x = new B(6) // Doesn't work, because I can't replace the object created on the line above with this new one.
x.value = new A(6) // Doesn't work, because I can't replace the object assigned to B.value for a new one.
x.value.value = 6 // Works, because A.value can receive a new object.
}
}
Итак, хотя мы не можем изменить объект, присвоенный x
, мы могли бы изменить состояние этого объекта. Однако в основе его лежало:--7-->.
теперь неизменность-хорошая вещь по многим причинам. Во-первых, если объект не измените внутреннее состояние, вам не нужно беспокоиться, если какая-то другая часть вашего кода меняет его. Например:
x = new B(0)
f(x)
if (x.value.value == 0)
println("f didn't do anything to x")
else
println("f did something to x")
это становится особенно важным с многопоточными системами. В многопоточной системе может произойти следующее:
x = new B(1)
f(x)
if (x.value.value == 1) {
print(x.value.value) // Can be different than 1!
}
если вы используете val
исключительно и использовать только неизменяемые структуры данных (то есть избегать массивов, все в scala.collection.mutable
, etc.), вы можете быть уверены, что этого не случится. То есть, если нет какого-то кода, возможно, даже фреймворк, делающий трюки отражения -- отражение может изменить "неизменные" ценности, к сожалению.
var
для различных целей. Это имеет некоторые проблемы:
- людям, читающим код, будет сложнее узнать, какое значение переменной в определенной части кода.
- вы можете забыть повторно инициализировать переменная в некотором пути кода и в конечном итоге передает неправильные значения вниз по потоку в коде.
проще говоря, используя val
безопаснее и приводит к более читабельный код.
тогда мы можем пойти в другом направлении. Если val
это лучше, почему есть var
на всех? Ну, некоторые языки сделали этот маршрут, но есть ситуации, в которых изменчивость улучшает производительность, много.
например, возьмите неизменяемый Queue
. Когда ты либо enqueue
или dequeue
вещи в нем, вы получаете новый
разница в том, что var
может быть повторно назначен в то время как val
не может. Изменчивость или иначе того, что фактически назначено, является побочной проблемой:
import collection.immutable
import collection.mutable
var m = immutable.Set("London", "Paris")
m = immutable.Set("New York") //Reassignment - I have change the "value" at m.
при этом:
val n = immutable.Set("London", "Paris")
n = immutable.Set("New York") //Will not compile as n is a val.
и отсюда:
val n = mutable.Set("London", "Paris")
n = mutable.Set("New York") //Will not compile, even though the type of n is mutable.
если вы строите структуру данных и все ее поля val
s, тогда эта структура данных неизменна, поскольку ее состояние не может измениться.
мышление в терминах C++,
val x: T
аналогично константный указатель на неконстантные данные
T* const x;
пока
var x: T
аналогично не-константный указатель на неконстантные данные
T* x;
пользу val
над var
увеличивает неизменяемость кодовой базы, что может облегчить ее корректность, параллелизм и понятность.
"val означает неизменяемый, а var означает изменяемый."
перефразируя, "val означает значение, а var означает переменную".
различие, которое оказывается чрезвычайно важным в вычислениях (потому что эти два понятия определяют саму суть того, что такое программирование), и что ОО удалось почти полностью размыть, потому что в ОО единственная аксиома заключается в том, что "все является объектом". И что, как следствие, многие программисты в наши дни, как правило, не понять/оценить / признать, потому что им промыли мозги, чтобы они "думали только ОО". Часто приводит к переменным / изменяемым объектам, используемым как везде, когда значение / неизменяемые объекты могли бы / часто были бы лучше.
val означает неизменяемый, а var означает изменяемый
вы можете думать val
как язык программирования java final
ключевой мир или язык C++const
ключ мира。
A вал похож на конечную переменную в Java. После инициализации вал невозможно переназначить.
A var, напротив, похож на не конечную переменную в Java. А var смогите быть переназначено в течении своей продолжительности жизни.
Val-значения являются типизированными константами хранения. После создания его значение не может быть повторно присвоено. новое значение можно определить с помощью ключевого слова val.
например. val x: Int = 5
здесь тип является необязательным, поскольку scala может вывести его из назначенного значения.
var - переменные-это типизированные единицы хранения, которым можно назначить значения снова, пока зарезервировано пространство памяти.
например. var x: Int = 5
данные, хранящиеся в единицах хранения автоматически де-распределяется JVM, как только они больше не нужны.
в scala значения предпочтительнее переменных из-за стабильности, которые они приносят в код, особенно в параллельном и многопоточном коде.
хотя многие уже ответили на разницу между Вал и var. Но следует заметить, что val не совсем как final ключевое слово.
мы можем изменить значение val с помощью рекурсии, но мы никогда не сможем изменить значение final. Final более постоянен, чем Val.
def factorial(num: Int): Int = {
if(num == 0) 1
else factorial(num - 1) * num
}
параметры метода по умолчанию val и при каждом вызове значение изменяется.