class Person(val name:String,var age:Int )
def person = new Person("Kumar",12)
person.age = 20
println(person.age)
Garis-garis ini menghasilkan kode 12
, meskipun person.age=20
telah berhasil dieksekusi. Saya menemukan bahwa ini terjadi karena saya menggunakan def di def person = new Person("Kumar",12)
. Jika saya menggunakan var atau val outputnya 20
. Saya mengerti defaultnya adalah val di scala. Ini:
def age = 30
age = 45
... memberikan kesalahan kompilasi karena ini adalah val secara default. Mengapa rangkaian baris pertama di atas tidak berfungsi dengan baik, namun juga tidak salah?
val
dapat diubah tetapi objek yang dirujuk oleh val tidak bisa. Aval
bukan konstanta.List
sebagaifinal
, tetapi dapat memodifikasi isinya.Saya akan mulai dengan perbedaan yang ada di Scala antara def , val dan var .
def - mendefinisikan label abadi untuk konten sisi kanan yang malas dievaluasi - mengevaluasi dengan nama.
val - mendefinisikan label permanen untuk konten sisi kanan yang bersemangat / segera dievaluasi - dievaluasi oleh nilai.
var - mendefinisikan variabel yang dapat diubah , yang awalnya diatur ke konten sisi kanan yang dievaluasi.
Contoh, def
Contoh, val
Contoh, var
Menurut di atas, label dari def dan val tidak dapat dipindahkan, dan jika ada kesalahan seperti di bawah ini akan muncul:
Ketika kelas didefinisikan seperti:
dan kemudian dipakai dengan:
label yang tidak dapat diubah dibuat untuk instance spesifik Person (yaitu 'personA'). Kapan pun 'usia' bidang yang dapat diubah perlu diubah, upaya tersebut gagal:
seperti yang diharapkan, 'usia' adalah bagian dari label yang tidak dapat diubah. Cara yang benar untuk mengerjakan ini terdiri dari menggunakan variabel yang bisa berubah, seperti dalam contoh berikut:
sejelas itu, dari referensi variabel yang bisa berubah-ubah (yaitu 'personB') dimungkinkan untuk memodifikasi bidang 'kelas' yang bisa berubah-ubah kelas.
Saya masih akan menekankan fakta bahwa semuanya berasal dari perbedaan yang disebutkan di atas, yang harus jelas dalam pikiran setiap programmer Scala.
sumber
personA
et al. sepertinya tidak aktif. Apakah memodifikasiage
anggota berfungsi atau tidak, terlepas dari apakah Anda menggunakandef personA
atau tidakvar personB
. Perbedaannya adalah bahwa dalamdef personA
kasus Anda memodifikasiPerson
-instance yang dikembalikan dari evaluasi pertama AndapersonA
. Mesin virtual ini dimodifikasi, tetapi ini bukan apa yang dikembalikan ketika Anda sekali lagi mengevaluasipersonA
. Sebagai gantinya, kedua kalinya Anda melakukannya,personA.age
Anda melakukannya dengan efektifnew Person("Tim",25).age
.Dengan
Anda mendefinisikan variabel fungsi / malas yang selalu mengembalikan contoh Orang baru dengan nama "Kumar" dan usia 12. Ini benar-benar valid dan kompiler tidak punya alasan untuk mengeluh. Memanggil person.age akan mengembalikan usia instance Person yang baru dibuat ini, yang selalu berusia 12.
Saat menulis
Anda menetapkan nilai baru ke properti umur di kelas Person, yang berlaku sejak usia dinyatakan sebagai
var
. Kompiler akan mengeluh jika Anda mencoba untuk menetapkan kembaliperson
dengan objek Orang baru sepertisumber
Untuk memberikan perspektif lain, "def" dalam Scala berarti sesuatu yang akan dievaluasi setiap kali digunakan, sementara val adalah sesuatu yang dievaluasi segera dan hanya sekali . Di sini, ungkapan
def person = new Person("Kumar",12)
itu menyatakan bahwa setiap kali kita menggunakan "orang" kita akan mendapatnew Person("Kumar",12)
panggilan. Oleh karena itu wajar bahwa kedua "person.age" tidak berhubungan.Ini adalah cara saya memahami Scala (mungkin dengan cara yang lebih "fungsional"). Saya tidak yakin jika
benar-benar apa yang dimaksudkan Scala. Saya tidak terlalu suka berpikir seperti itu setidaknya ...
sumber
Seperti yang sudah dikatakan Kintaro, orang adalah metode (karena def) dan selalu mengembalikan contoh Orang baru. Seperti yang Anda tahu itu akan berhasil jika Anda mengubah metode ke var atau val:
Kemungkinan lain adalah:
Namun,
person.age=20
dalam kode Anda diizinkan, saat Anda mendapatkan kembaliPerson
instance dariperson
metode, dan pada contoh ini Anda diizinkan untuk mengubah nilai avar
. Masalahnya adalah, bahwa setelah baris itu Anda tidak lagi memiliki referensi ke instance tersebut (karena setiap panggilanperson
akan menghasilkan instance baru).Ini tidak istimewa, Anda akan memiliki perilaku yang persis sama di Jawa:
sumber
Mari kita ambil ini:
dan menulis ulang dengan kode yang setara
Lihat,
def
adalah metode. Itu akan mengeksekusi setiap kali dipanggil, dan setiap kali itu akan kembali (a)new Person("Kumar", 12)
. Dan ini bukan kesalahan dalam "tugas" karena itu sebenarnya bukan tugas, tetapi hanya panggilan keage_=
metode (disediakan olehvar
).sumber