Dan pemula Kotlin bertanya, "mengapa kode berikut tidak dapat dikompilasi?":
var left: Node? = null
fun show() {
if (left != null) {
queue.add(left) // ERROR HERE
}
}
Pemain pintar ke 'Node' tidak mungkin, karena 'kiri' adalah properti yang bisa berubah yang bisa diubah saat ini
Saya mendapatkan itu left
adalah variabel yang bisa berubah-ubah, tapi saya secara eksplisit memeriksa left != null
dan left
bertipe Node
jadi mengapa tidak bisa dicor-pintar ke tipe itu?
Bagaimana saya bisa memperbaikinya dengan elegan? :)
n.left?.let { queue.add(it) }
saya pikir?Jawaban:
Antara eksekusi
left != null
danqueue.add(left)
utas lainnya dapat mengubah nilaileft
menjadinull
.Untuk mengatasinya Anda memiliki beberapa opsi. Inilah beberapa:
Gunakan variabel lokal dengan smart cast:
Gunakan panggilan aman seperti salah satu dari yang berikut:
Gunakan operator Elvis dengan
return
untuk kembali lebih awal dari fungsi melampirkan:Perhatikan bahwa
break
dancontinue
dapat digunakan secara serupa untuk pemeriksaan dalam loop.sumber
Node
kelas yang didefinisikan dalam versi asli dari pertanyaan yang memiliki potongan kode yang lebih rumitn.left
daripada hanyaleft
. Saya telah memperbarui jawabannya. Terima kasih.val
untuk masing-masingvar
, membuat beberapa?.let
pernyataan, atau menggunakan beberapa?: return
pernyataan tergantung pada fungsi Anda. misMyAsyncTask().execute(a1 ?: return, a2 ?: return, a3 ?: return)
. Anda juga dapat mencoba salah satu solusi untuk "membiarkan banyak variabel" .1) Anda juga dapat menggunakan
lateinit
Jika Anda yakin melakukan inisialisasi nantionCreate()
atau di tempat lain.Gunakan ini
Alih-alih ini
2) Dan ada cara lain yang menggunakan
!!
variabel akhir saat Anda menggunakannya seperti inisumber
Ada opsi keempat selain yang ada di jawaban mfulton26.
Dengan menggunakan
?.
operator dimungkinkan untuk memanggil metode serta bidang tanpa berurusan denganlet
atau menggunakan variabel lokal.Beberapa kode untuk konteks:
Ini bekerja dengan metode, bidang dan semua hal lain yang saya coba untuk membuatnya berfungsi.
Jadi untuk menyelesaikan masalah, alih-alih harus menggunakan gips manual atau menggunakan variabel lokal, Anda dapat menggunakan
?.
untuk memanggil metode.Untuk referensi, ini diuji di Kotlin
1.1.4-3
, tetapi juga diuji di1.1.51
dan1.1.60
. Tidak ada jaminan itu berfungsi pada versi lain, itu bisa menjadi fitur baru.Menggunakan
?.
operator tidak dapat digunakan dalam kasus Anda karena variabel yang diteruskan itulah masalahnya. Operator Elvis dapat digunakan sebagai alternatif, dan mungkin salah satu yang membutuhkan jumlah kode paling sedikit. Alih-alih menggunakancontinue
sekalipun,return
bisa juga digunakan.Menggunakan casting manual juga bisa menjadi pilihan, tetapi ini bukan nol aman:
Berarti jika kiri telah berubah pada utas yang berbeda, program akan macet.
sumber
left
dan tidakqueue
. Perlu memeriksa ini, akan mengedit jawabannya dalam satu menitAlasan praktis mengapa ini tidak berhasil tidak terkait dengan utas. Intinya adalah yang
node.left
diterjemahkan secara efektif ke dalamnode.getLeft()
.Pencari properti ini dapat didefinisikan sebagai:
Karenanya dua panggilan mungkin tidak mengembalikan hasil yang sama.
sumber
Ubah
var left: Node? = null
kelateinit var left: Node
. Masalah terpecahkan.sumber
Melakukan hal ini:
Yang tampaknya menjadi opsi pertama yang disediakan oleh jawaban yang diterima, tetapi itulah yang Anda cari.
sumber
Agar ada Smart Cast dari properti, tipe data dari properti harus kelas yang berisi metode atau perilaku yang ingin Anda akses dan BUKAN bahwa properti itu dari tipe kelas super.
misalnya di Android
Menjadi:
Larutan:
Pemakaian:
GL
sumber
Solusi Anda yang paling elegan harus:
Maka Anda tidak perlu mendefinisikan variabel lokal baru dan tidak perlu, dan Anda tidak memiliki pernyataan atau gips baru (yang bukan KERING). Fungsi lingkup lain juga bisa berfungsi jadi pilih favorit Anda.
sumber
Coba gunakan operator pernyataan tidak-nol ...
sumber
Bagaimana saya akan menulisnya:
sumber