Cách tốt nhất để kiểm tra vô hiệu trong Kotlin?


Câu trả lời:


62

Cả hai cách tiếp cận đều tạo ra cùng một mã bytecode để bạn có thể chọn bất cứ thứ gì bạn thích.


4
. Nếu tôi hiểu nó một cách chính xác sau đó ông được yêu cầu cách tốt nhất để kiểm tra null trong Kotlin, không có cách tiếp cận tốt nhất tạo ra byte-code @ BenitoBertoli câu trả lời vẻ hứa hẹn, đó là làm giảm mã boilerplate
imgs

155

Một bình đẳng cấu trúc a == bđược dịch thành

a?.equals(b) ?: (b === null)

Do đó, khi so sánh với null, bình đẳng cấu trúc a == nullđược chuyển thành bình đẳng tham chiếu a === null.

Theo tài liệu , không có ích lợi gì trong việc tối ưu hóa mã của bạn, vì vậy bạn có thể sử dụng a == nulla != null


Lưu ý rằng nếu biến là thuộc tính có thể thay đổi, bạn sẽ không thể truyền thông minh nó sang kiểu không thể null bên trong ifcâu lệnh (bởi vì giá trị có thể đã được sửa đổi bởi một chuỗi khác) và letthay vào đó bạn phải sử dụng toán tử cuộc gọi an toàn .

Tổng đài cuộc gọi an toàn ?.

a?.let {
   // not null do something
   println(it)
   println("not null")
}


Bạn có thể sử dụng nó kết hợp với toán tử Elvis.

Người điều hành Elvis ?: (Tôi đoán vì dấu thẩm vấn trông giống như tóc của Elvis)

a ?: println("null")

Và nếu bạn muốn chạy một khối mã

a ?: run {
    println("null")
    println("The King has left the building")
}

Kết hợp cả hai

a?.let {
   println("not null")
   println("Wop-bop-a-loom-a-boom-bam-boom")
} ?: run {
    println("null")
    println("When things go null, don't go with them")
}

1
tại sao bạn không sử dụng ifđể kiểm tra null? a?.let{} ?: run{}chỉ thích hợp trong một số trường hợp hiếm hoi, nếu không thì nó không phải là thành ngữ
voddan

2
@voddan Tôi không đề nghị không sử dụng nếu để nullkiểm tra, tôi đang liệt kê các tùy chọn khả thi khác. Mặc dù tôi không chắc liệu runcó bị phạt hay không. Tôi sẽ cập nhật câu trả lời của mình để làm cho nó rõ ràng hơn.
Benito Bertoli

1
@voddan Nếu alà a var, thì sử dụng a?.let{} ?: run{}đảm bảo rằng nó sẽ được ràng buộc đúng trong letphạm vi cho toàn bộ. Nếu alà a val, thì không có sự khác biệt.
madeinqc

1
@madeinqc nếu a là a valthì dùng let sẽ khác và dở tệ. Tôi thấy bài viết này giải thích nó rất tốt - Kotlin: Đừng chỉ sử dụng LET để kiểm tra null .
Sufian

39

Kotlin cách xử lý null

Hoạt động truy cập an toàn

val dialog : Dialog? = Dialog()
dialog?.dismiss()  // if the dialog will be null,the dismiss call will be omitted

Để chức năng

user?.let {
  //Work with non-null user
  handleNonNullUser(user)
}

Xuất cảnh sớm

fun handleUser(user : User?) {
  user ?: return //exit the function if user is null
  //Now the compiler knows user is non-null
}

Bóng bất biến

var user : User? = null

fun handleUser() {
  val user = user ?: return //Return if null, otherwise create immutable shadow
  //Work with a local, non-null variable named user
}

Giá trị mặc định

fun getUserName(): String {
 //If our nullable reference is not null, use it, otherwise use non-null value 
 return userName ?: "Anonymous"
}

Sử dụng val thay vì var

vallà chỉ đọc, varcó thể thay đổi. Bạn nên sử dụng càng nhiều thuộc tính chỉ đọc càng tốt, chúng an toàn cho chuỗi.

Sử dụng lateinit

Đôi khi bạn không thể sử dụng thuộc tính bất biến. Ví dụ: nó xảy ra trên Android khi một số thuộc tính được khởi tạo trong onCreate()cuộc gọi. Đối với những tình huống này, Kotlin có một tính năng ngôn ngữ được gọi là lateinit.

private lateinit var mAdapter: RecyclerAdapter<Transaction>

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   mAdapter = RecyclerAdapter(R.layout.item_transaction)
}

fun updateTransactions() {
   mAdapter.notifyDataSetChanged()
}

Tôi muốn gọi giá trị cuối cùng là "giá trị mặc định" (không phải elvis), vì 3/4 trong số đó đang sử dụng elvis.
AjahnCharles

@AjahnCharles có lý))
Levon Petrosyan

1
Đây là rác, bất kỳ ngôn ngữ hiện đại nào cũng có thể xử lý các tùy chọn tốt hơn thế này. nó là một công việc vặt hơn là một lợi ích cho các lập trình viên.
JBarros35

10

Bổ sung cho @Benito Bertoli,

sự kết hợp thực sự không giống if-else

"test" ?. let {
    println ( "1. it=$it" )
} ?: let {
    println ( "2. it is null!" )
}

Kết quả là:

1. it=test

Nhưng nếu:

"test" ?. let {
    println ( "1. it=$it" )
    null // finally returns null
} ?: let {
    println ( "2. it is null!" )
}

Kết quả là:

1. it=test
2. it is null!

Ngoài ra, nếu sử dụng elvis trước:

null ?: let {
    println ( "1. it is null!" )
} ?. let {
    println ( "2. it=$it" )
}

Kết quả là:

1. it is null!
2. it=kotlin.Unit

5

Kiểm tra các phương pháp hữu ích, nó có thể hữu ích:

/**
 * Performs [R] when [T] is not null. Block [R] will have context of [T]
 */
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
    return input?.let(callback)
}

/**
 * Checking if [T] is not `null` and if its function completes or satisfies to some condition.
 */
inline fun <T: Any> T?.isNotNullAndSatisfies(check: T.() -> Boolean?): Boolean{
    return ifNotNull(this) { it.run(check) } ?: false
}

Dưới đây là ví dụ có thể có về cách sử dụng các chức năng đó:

var s: String? = null

// ...

if (s.isNotNullAndSatisfies{ isEmpty() }{
   // do something
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.