8-bo‘lim
Null xavfsizligi
String va String? farqi, xavfsiz chaqiruv, Elvis operatori, !! belgisining xavfi, let, as? va null bilan ishlashning to'g'ri usullari.
Ushbu bo‘lim mundarijasi
Bu - Kotlin ning eng muhim bo'limi. Til shu muammoni hal qilish uchun yaratilgan desak, mubolag'a bo'lmaydi.
Ikki xil tur #
fun main() {
val bor: String = "matn"
val yoq: String? = null
println(bor.length)
println(yoq)
}
4
null
String va String? - bu ikkita boshqa-boshqa tur:
Stringganullberib bo'lmaydi.String?ga berish mumkin, lekin uni tekshirmasdan ishlatib bo'lmaydi.
// error: null can not be a value of a non-null type
val bor: String = null
val yoq: String? = null
// error: only safe (?.) or non-null (!!) calls allowed
println(yoq.length)
Ikkala xato ham kompilyatsiya paytida chiqadi - dastur ishga ham tushmaydi.
NullPointerException - dasturlash tarixidagi eng ko'p uchraydigan
xato. U dastur ishlayotganda, ko'pincha foydalanuvchi oldida
yuz beradi.
Kotlin uni kompilyatsiya paytiga ko'chiradi. Ya'ni xato bor bo'lsa, dastur mijozga yetib ham bormaydi.
Buning evaziga siz bir narsa qilishingiz kerak: qaysi qiymat bo'sh
bo'lishi mumkinligini aniq aytish. ? belgisi aynan shu.
Xavfsiz chaqiruv #
fun main() {
val bor: String? = "Namangan"
val yoq: String? = null
println(bor?.length)
println(yoq?.length)
println(yoq?.uppercase()?.reversed())
}
8
null
null
?. - "agar null bo'lmasa chaqir, bo'lsa null qaytar".
Zanjir ham xavfsiz: birinchi bo'g'in null bo'lsa, qolganlari
umuman bajarilmaydi.
Elvis operatori #
fun main() {
val yoq: String? = null
val bor: String? = "matn"
println(yoq ?: "standart qiymat")
println(bor ?: "standart qiymat")
println(yoq?.length ?: 0)
val uzunlik = bor?.length ?: -1
println(uzunlik)
}
standart qiymat
matn
0
4
?: - "chapdagi null bo'lsa, o'ngdagini ol".
Belgini yon tomonga qiyshaytirib qarang: ?: - bu ko'zlar va
Elvis Presli ning mashhur turmagi.
Bu rasmiy nom emas, lekin dasturchilar orasida shu nom bilan tanilgan va Kotlin hujjatlarida ham shunday ataladi.
Elvis bilan erta chiqish #
fun uzunlik(matn: String?): Int {
val toza = matn?.trim() ?: return -1
return toza.length
}
fun main() {
println(uzunlik(" salom "))
println(uzunlik(null))
}
5
-1
?: ning o'ng tomonida return yoki throw bo'lishi mumkin. Bu
"qiymat bo'lmasa, bu yerda to'xta" degan qisqa shakl.
!! - eng xavfli belgi #
fun main() {
val bor: String? = "matn"
println(bor!!.length)
}
4
!! - "men bu yerda null yo'qligiga kafolat beraman".
Agar kafolatingiz noto'g'ri bo'lsa, !! aynan siz qochmoqchi bo'lgan
NullPointerException ni beradi:
val yoq: String? = null
println(yoq!!.length)
Exception in thread "main" java.lang.NullPointerException
Ya'ni !! - Kotlin ning himoyasini o'chirib qo'yish tugmasi.
Uni ko'rganingizda o'zingizdan so'rang: bu qiymat nega bo'sh
bo'lolmaydi? Agar javob aniq bo'lsa, kodni shunday qayta yozing-ki,
kompilyator ham buni ko'rsin. Deyarli har doim ?., ?: yoki
tekshiruv yaxshiroq yechim beradi.
Tekshiruvdan keyin aqlli aylantirish #
fun tavsif(matn: String?): String {
if (matn == null) {
return "qiymat yo'q"
}
return "uzunligi ${matn.length}, katta harfda ${matn.uppercase()}"
}
fun main() {
println(tavsif("salom"))
println(tavsif(null))
}
uzunligi 5, katta harfda SALOM
qiymat yo'q
if (matn == null) return dan keyin kompilyator matn ning
null emasligini biladi va ?. yozish kerak emas. Bu yana o'sha
aqlli aylantirish.
let #
fun main() {
val ism: String? = "Malika"
val yoq: String? = null
ism?.let {
println("Uzunlik: ${it.length}")
println("Katta harfda: ${it.uppercase()}")
}
yoq?.let {
println("bu chiqmaydi")
}
val natija = ism?.let { it.length * 2 } ?: 0
println(natija)
}
Uzunlik: 6
Katta harfda: MALIKA
12
?.let { } - "qiymat bor bo'lsa, shu blokni bajar". Blok ichida
qiymat it deb ataladi va u aniq null emas.
Bu bir nechta amal bajarish kerak bo'lganda qulay.
Xavfsiz aylantirish #
fun main() {
val qiymat: Any = "matn"
val matn: String? = qiymat as? String
val son: Int? = qiymat as? Int
println(matn)
println(son)
println(son ?: -1)
}
matn
null
-1
as? - "aylantirib ko'r, bo'lmasa null qaytar". Oddiy as esa
mos kelmasa dasturni to'xtatadi.
Kolleksiyalardagi null #
fun main() {
val ballar: List<Int?> = listOf(85, null, 92, null, 78)
println(ballar)
println(ballar.filterNotNull())
println(ballar.filterNotNull().sum())
println(ballar.count { it != null })
val ismlar: List<String>? = null
println(ismlar?.size ?: 0)
println(ismlar.orEmpty())
}
[85, null, 92, null, 78]
[85, 92, 78]
255
3
0
[]
| Vosita | Vazifasi |
|---|---|
filterNotNull() | null larni olib tashlaydi |
orEmpty() | null bo'lsa bo'sh ro'yxat beradi |
?.size ?: 0 | Xavfsiz o'lcham |
Funksiya ro'yxat qaytarishi kerak bo'lsa, hech narsa topilmaganda
null emas, bo'sh ro'yxat qaytaring.
Shunda chaqiruvchi tekshirmasdan ishlatadi - bo'sh ro'yxat bo'ylab yurish xato bermaydi, shunchaki hech narsa bajarilmaydi.
Bu kichik odat null tekshiruvlarining yarmini yo'q qiladi.
Null bilan ishlashni tanlash #
Amaliy misol #
data class Manzil(val shahar: String, val kocha: String?)
data class Foydalanuvchi(val ism: String, val manzil: Manzil?)
fun kochaNomi(f: Foydalanuvchi?): String =
f?.manzil?.kocha ?: "ko'rsatilmagan"
fun main() {
val a = Foydalanuvchi("Malika", Manzil("Namangan", "Navoiy"))
val b = Foydalanuvchi("Aziza", Manzil("Andijon", null))
val c = Foydalanuvchi("Nodira", null)
println(kochaNomi(a))
println(kochaNomi(b))
println(kochaNomi(c))
println(kochaNomi(null))
}
Navoiy
ko'rsatilmagan
ko'rsatilmagan
ko'rsatilmagan
Bitta qator - f?.manzil?.kocha ?: "..." - to'rtta holatni ham
to'g'ri hal qiladi. Java da bu uchta ichma-ich if bo'lardi.
Java dan kelgan qiymatlar #
Kotlin Java kutubxonasini chaqirganda muammo bor: Java tizimida "bu qiymat null bo'la oladimi" degan ma'lumot yo'q.
Bunday qiymatlar platforma turi deb ataladi va hujjatlarda
String! shaklida ko'rsatiladi. Kompilyator ularga ishonadi va
tekshirishni talab qilmaydi.
Ya'ni Java kodi bilan chegarada Kotlin ning kafolati tugaydi. Java metodidan kelgan qiymatni o'zingiz tekshiring yoki darhol aniq turga o'tkazing:
val natija: String? = javaObyekt.metod()
Stringganullberishga urinib, xato matnini yozing.String?ni tekshirmasdan ishlatishga urining.?.bilan zanjirli chaqiruv yozing.?:bilan zaxira qiymat bering.?: returnshaklini funksiyada ishlating.!!bilannullga murojaat qilib, xato turini ko'ring.if (x == null) returndan keyin?.kerak emasligini tekshiring.?.let { }bilan ikkita amal bajaring.as?bilan xavfsiz aylantiring.List<Int?>danfilterNotNull()bilan sonlarni ajrating.
Xulosa #
StringvaString?- ikki xil tur; birinchisiganullberib bo'lmaydi.- Kotlin
NullPointerExceptionni kompilyatsiya paytiga ko'chiradi. ?.- xavfsiz chaqiruv, zanjir bo'ylab ham ishlaydi.?:(Elvis) - zaxira qiymat; o'ng tomonidareturnham bo'ladi.!!- himoyani o'chiradi vaNullPointerExceptionberadi; undan qoching.nulltekshiruvidan keyin aqlli aylantirish ishlaydi.?.let { }- qiymat bor bo'lganda bir nechta amal uchun.as?- xavfsiz aylantirish.- Funksiyadan
nullemas, bo'sh ro'yxat qaytaring.
Keyingi bo'limda kolleksiyalarni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.