Tôi nên sử dụng gấp đôi =
hay gấp ba =
?
if(a === null) {
//do something
}
hoặc là
if(a == null) {
//do something
}
Tương tự cho 'không bằng':
if(a !== null) {
//do something
}
hoặc là
if(a != null) {
//do something
}
Tôi nên sử dụng gấp đôi =
hay gấp ba =
?
if(a === null) {
//do something
}
hoặc là
if(a == null) {
//do something
}
Tương tự cho 'không bằng':
if(a !== null) {
//do something
}
hoặc là
if(a != null) {
//do something
}
Câu trả lời:
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.
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 == null
và a != 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 if
câu lệnh (bởi vì giá trị có thể đã được sửa đổi bởi một chuỗi khác) và let
thay 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")
}
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ữ
null
kiể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 run
có 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.
a
là a var
, thì sử dụng a?.let{} ?: run{}
đảm bảo rằng nó sẽ được ràng buộc đúng trong let
phạm vi cho toàn bộ. Nếu a
là a val
, thì không có sự khác biệt.
val
thì 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 .
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
val
là chỉ đọc, var
có 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()
}
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
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
}