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.

🕑 14 daqiqa o‘qish 📄 691 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Ikki xil tur
  2. Xavfsiz chaqiruv
  3. Elvis operatori
  4. Elvis bilan erta chiqish
  5. !! - eng xavfli belgi
  6. Tekshiruvdan keyin aqlli aylantirish
  7. let
  8. Xavfsiz aylantirish
  9. Kolleksiyalardagi null
  10. Null bilan ishlashni tanlash
  11. Amaliy misol
  12. Java dan kelgan qiymatlar
  13. Xulosa

Bu - Kotlin ning eng muhim bo'limi. Til shu muammoni hal qilish uchun yaratilgan desak, mubolag'a bo'lmaydi.

Ikki xil tur #

KOTLIN
fun main() {
    val bor: String = "matn"
    val yoq: String? = null

    println(bor.length)
    println(yoq)
}
Natija
4
null

String va String? - bu ikkita boshqa-boshqa tur:

  • String ga null berib bo'lmaydi.
  • String? ga berish mumkin, lekin uni tekshirmasdan ishlatib bo'lmaydi.
KOTLIN
// 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.

Nega bu shunchalik muhim

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 #

KOTLIN
fun main() {
    val bor: String? = "Namangan"
    val yoq: String? = null

    println(bor?.length)
    println(yoq?.length)
    println(yoq?.uppercase()?.reversed())
}
Natija
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 #

KOTLIN
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)
}
Natija
standart qiymat
matn
0
4

?: - "chapdagi null bo'lsa, o'ngdagini ol".

Nega "Elvis"

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 #

KOTLIN
fun uzunlik(matn: String?): Int {
    val toza = matn?.trim() ?: return -1
    return toza.length
}

fun main() {
    println(uzunlik("  salom  "))
    println(uzunlik(null))
}
Natija
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 #

KOTLIN
fun main() {
    val bor: String? = "matn"
    println(bor!!.length)
}
Natija
4

!! - "men bu yerda null yo'qligiga kafolat beraman".

!! ni ishlatmaslikka harakat qiling

Agar kafolatingiz noto'g'ri bo'lsa, !! aynan siz qochmoqchi bo'lgan NullPointerException ni beradi:

KOTLIN
val yoq: String? = null
println(yoq!!.length)
Natija
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 #

KOTLIN
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))
}
Natija
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 #

KOTLIN
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)
}
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 #

KOTLIN
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)
}
Natija
matn
null
-1

as? - "aylantirib ko'r, bo'lmasa null qaytar". Oddiy as esa mos kelmasa dasturni to'xtatadi.

Kolleksiyalardagi null #

KOTLIN
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())
}
Natija
[85, null, 92, null, 78]
[85, 92, 78]
255
3
0
[]
VositaVazifasi
filterNotNull()null larni olib tashlaydi
orEmpty()null bo'lsa bo'sh ro'yxat beradi
?.size ?: 0Xavfsiz o'lcham
Null qaytarmaslikka harakat qiling

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 #

Qiymat null bo'lishi mumkin - nima qilish kerak? ?. bitta chaqiruv, natija null bo'lsa mayli ?: zaxira qiymat yoki erta return ?.let { } bir nechta amal qiymat bor bo'lsa !! deyarli hech qachon oxirgi chora Eng yaxshisi esa - qiymatni umuman null qilmaslik. Ro'yxat o'rniga bo'sh ro'yxat, matn o'rniga bo'sh matn qaytaring. Har bir ? belgisi - o'ylangan qaror bo'lsin "shunchaki ehtiyot uchun" qo'yilgan ? faqat ish qo'shadi
Tanlov qiymat bo'lmaganda nima qilish kerakligiga bog'liq

Amaliy misol #

KOTLIN
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))
}
Natija
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 #

Platforma turlari

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:

KOTLIN
val natija: String? = javaObyekt.metod()
Amaliy topshiriq
  1. String ga null berishga urinib, xato matnini yozing.
  2. String? ni tekshirmasdan ishlatishga urining.
  3. ?. bilan zanjirli chaqiruv yozing.
  4. ?: bilan zaxira qiymat bering.
  5. ?: return shaklini funksiyada ishlating.
  6. !! bilan null ga murojaat qilib, xato turini ko'ring.
  7. if (x == null) return dan keyin ?. kerak emasligini tekshiring.
  8. ?.let { } bilan ikkita amal bajaring.
  9. as? bilan xavfsiz aylantiring.
  10. List<Int?> dan filterNotNull() bilan sonlarni ajrating.

Xulosa #

  • String va String? - ikki xil tur; birinchisiga null berib bo'lmaydi.
  • Kotlin NullPointerException ni kompilyatsiya paytiga ko'chiradi.
  • ?. - xavfsiz chaqiruv, zanjir bo'ylab ham ishlaydi.
  • ?: (Elvis) - zaxira qiymat; o'ng tomonida return ham bo'ladi.
  • !! - himoyani o'chiradi va NullPointerException beradi; undan qoching.
  • null tekshiruvidan keyin aqlli aylantirish ishlaydi.
  • ?.let { } - qiymat bor bo'lganda bir nechta amal uchun.
  • as? - xavfsiz aylantirish.
  • Funksiyadan null emas, bo'sh ro'yxat qaytaring.

Keyingi bo'limda kolleksiyalarni o'rganamiz.

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.