Câu trả lời:
Bạn có thể sử dụng letchức năng như sau:
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
Lưu ý rằng bạn chỉ cần gọi runhàm nếu bạn cần một khối mã. Bạn có thể loại bỏ run-block nếu bạn chỉ có một dòng kẻ sau toán tử elvis-operator ( ?:).
Hãy lưu ý rằng runkhối sẽ được đánh giá nếu blà null hoặc nếu let-block được đánh giá là null.
Bởi vì điều này, bạn thường chỉ muốn một ifbiểu thức.
val a = if (b == null) {
// ...
} else {
// ...
}
Trong trường hợp này, else-block sẽ chỉ được đánh giá nếu bkhông phải là null.
achưa được xác định trong phạm vi của letvà run. Nhưng bạn có thể truy cập giá trị của bbên trong letvới tham số ngầm định it. Điều này phục vụ cùng một mục đích tôi đoán.
atrước các khối mã đó. Và acó thể được truy cập vào bên trong.
acái gì? Nếu nó là b, sau đó itphục vụ cùng một mục đích. Nó có gán lại avới kết quả của val-block không?
ittừ bên trong letkhối. Kết quả của khối lethoặc runsẽ được gán cho a. Kết quả là biểu thức cuối cùng trong khối. Bạn sử dụng bài tập sau khi let / runđã hoàn thành, giống như bạn làm với bất kỳ bài tập bình thường nào khác.
Trước tiên, hãy đảm bảo rằng chúng ta hiểu ngữ nghĩa của thành ngữ Swift được cung cấp:
if let a = <expr> {
// then-block
}
else {
// else-block
}
Nó có nghĩa là: "nếu <expr>kết quả là tùy chọn không phải là nil, hãy nhập then-block với ký hiệu được aliên kết với giá trị không được bao bọc. Nếu không, hãy nhập elsekhối.
Đặc biệt lưu ý rằng chỉa bị ràng buộc trong then-block . Trong Kotlin, bạn có thể dễ dàng nhận được điều này bằng cách gọi
<expr>?.also { a ->
// then-block
}
và bạn có thể thêm một else-block như sau:
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
Điều này dẫn đến ngữ nghĩa giống như thành ngữ Swift.
Câu trả lời của tôi hoàn toàn là một con mèo sao chép từ những người khác. Tuy nhiên, tôi không thể hiểu được biểu hiện của họ một cách dễ dàng. Vì vậy, tôi đoán sẽ rất vui nếu cung cấp một câu trả lời dễ hiểu hơn.
Nhanh chóng:
if let a = b.val {
//use "a" as unwrapped
}
else {
}
Trong Kotlin:
b.val?.let{a ->
//use "a" as unwrapped
} ?: run{
//else case
}
letthay vì alsocó nghĩa là runkhối sẽ thực thi bất cứ khi nào letkhối trả về null, đó không phải là điều chúng ta muốn.
Không giống như Swift, không cần thiết phải mở gói tùy chọn trước khi sử dụng nó trong Kotlin. Chúng tôi chỉ có thể kiểm tra xem giá trị có phải là null hay không và trình biên dịch theo dõi thông tin về việc kiểm tra bạn đã thực hiện và cho phép sử dụng nó khi chưa được gói.
Trong Swift:
if let a = b.val {
//use "a" as unwrapped
} else {
}
Trong Kotlin:
if b.val != null {
//use "b.val" as unwrapped
} else {
}
Tham khảo Tài liệu: (null-safe) để biết thêm các trường hợp sử dụng như vậy
if let tuyên bố.Swift's Optional Binding(được gọi là if-letcâu lệnh) được sử dụng để tìm hiểu xem một tùy chọn có chứa một giá trị hay không và nếu có, để cung cấp giá trị đó dưới dạng một hằng số hoặc biến tạm thời. Vì vậy, an Optional Bindingcho if-letcâu lệnh như sau:
if-letTuyên bố của Swift :
let b: Int? = 50
if let a = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
Trong Kotlin, giống như trong Swift, để tránh sự cố do cố gắng truy cập giá trị null khi nó không được mong đợi, một cú pháp cụ thể (như b.let { }trong ví dụ thứ hai) được cung cấp để mở gói đúng cách nullable types:
Kotlin tương đương với 1
if-lettuyên bố của Swift :
val b: Int? = null
val a = b
if (a != null) {
println("Good news!")
} else {
println("Equal to 'null' or not set")
}
/* RESULT: Equal to 'null' or not set */
letHàm của Kotlin , khi được sử dụng kết hợp với toán tử cuộc gọi an toàn ?:, sẽ cung cấp một cách ngắn gọn để xử lý các biểu thức nullable.
Kotlin tương đương 2 (Hàm let inline và Toán tử Elvis) của
if-letcâu lệnh Swift :
val b: Int? = null
val a = b.let { nonNullable -> nonNullable } ?: "Equal to 'null' or not set"
println(a)
/* RESULT: Equal to 'null' or not set */
guard let tuyên bố.guard-letcâu lệnh trong Swift rất đơn giản và mạnh mẽ. Nó kiểm tra một số điều kiện và nếu nó được đánh giá là sai, thì elsecâu lệnh sẽ thực thi thông thường sẽ thoát khỏi một phương thức.
Hãy cùng khám phá
guard-lettuyên bố của Swift :
let b: Int? = nil
func testIt() {
guard let a = b else {
print("Equal to 'nil' or not set")
return
}
print("Good news!")
}
testIt()
/* RESULT: Equal to 'nil' or not set */
Hiệu ứng tương tự của Kotlin đối với
guard-lettuyên bố của Swift :
Không giống như Swift, trong Kotlin, không có tuyên bố bảo vệ nào cả. Tuy nhiên, bạn có thể sử dụng dấu Elvis Operator- ?:để có được hiệu ứng tương tự.
val b: Int? = 50
fun testIt() {
val a = b ?: return println("Equal to 'null' or not set")
return println("Good news!")
}
testIt()
/* RESULT: Good news! */
Hi vọng điêu nay co ich.
Đây là cách chỉ thực thi mã khi namekhông phải là null:
var name: String? = null
name?.let { nameUnwrapp ->
println(nameUnwrapp) // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
println(nameUnwrapp) // printed "Alex"
}
letlàm được, nhưng câu hỏi là về elsechiến lược thực thi nếu đối tượng letđược gọi là null. Swift có nó theo cách tự nhiên hơn (có thể tranh luận). Nhưng đã thực hiện cả Kotlin và Swift rất nhiều, tôi ước gì Kotlin có một cách mở đơn giản như Swift.
Đây là biến thể của tôi, được giới hạn trong trường hợp "nếu không phải là null" rất phổ biến.
Trước hết, hãy xác định điều này ở đâu đó:
inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
if (obj != null) {
block(obj)
}
}
Có lẽ nên như vậy internal, để tránh xung đột.
Bây giờ, hãy chuyển đổi mã Swift này:
if let item = obj.item {
doSomething(item)
}
Đối với mã Kotlin này:
ifNotNull(obj.item) { item ->
doSomething(item)
}
Lưu ý rằng như mọi khi với các khối trong Kotlin, bạn có thể bỏ đối số và sử dụng it:
ifNotNull(obj.item) {
doSomething(it)
}
Nhưng nếu khối nhiều hơn 1-2 dòng, có lẽ tốt nhất là phải rõ ràng.
Điều này tương tự như Swift mà tôi có thể tìm thấy.
Có một cách tương tự trong kotlin để đạt được phong cách if-let của Swift
if (val a = b) {
a.doFirst()
a.doSecond()
}
Bạn cũng có thể gán nhiều giá trị nullable
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
Cách tiếp cận này sẽ phù hợp hơn nếu các giá trị nullable được sử dụng nhiều hơn 1 lần. Theo tôi, nó giúp ích từ khía cạnh hiệu suất vì giá trị nullable sẽ chỉ được kiểm tra một lần.
nguồn: Kotlin Discussion
Tôi thêm câu trả lời này để làm rõ câu trả lời được chấp nhận vì nó quá lớn đối với một nhận xét.
Mô hình chung ở đây là bạn có thể sử dụng bất kỳ sự kết hợp nào của các Hàm Phạm vi có sẵn trong Kotlin được phân tách bằng Toán tử Elvis như sau:
<nullable>?.<scope function> {
// code if not null
} :? <scope function> {
// code if null
}
Ví dụ:
val gradedStudent = student?.apply {
grade = newGrade
} :? with(newGrade) {
Student().apply { grade = newGrade }
}
akhông thể truy cập vào bên trongletvàrunchặn.