Câu trả lời:
Bạn có thể sử dụng let
chứ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 run
hà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 run
khối sẽ được đánh giá nếu b
là 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 if
biể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 b
không phải là null.
a
chưa được xác định trong phạm vi của let
và run
. Nhưng bạn có thể truy cập giá trị của b
bên trong let
vớ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.
a
trước các khối mã đó. Và a
có thể được truy cập vào bên trong.
a
cái gì? Nếu nó là b
, sau đó it
phục vụ cùng một mục đích. Nó có gán lại a
với kết quả của val
-block không?
it
từ bên trong let
khối. Kết quả của khối let
hoặc run
sẽ đượ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 a
liên kết với giá trị không được bao bọc. Nếu không, hãy nhập else
khố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
}
let
thay vì also
có nghĩa là run
khối sẽ thực thi bất cứ khi nào let
khố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-let
câ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 Binding
cho if-let
câu lệnh như sau:
if-let
Tuyê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-let
tuyê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 */
let
Hà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-let
câ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-let
câ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ì else
câ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-let
tuyê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-let
tuyê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 name
khô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"
}
let
làm được, nhưng câu hỏi là về else
chiế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 }
}
a
không thể truy cập vào bên tronglet
vàrun
chặn.