Viết nhanh câu lệnh if let trong Kotlin


123

Trong Kotlin có tương đương với mã Swift bên dưới không?

if let a = b.val {

}
else {

}

Câu trả lời:


255

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.


41
Nó không tương đương. akhông thể truy cập vào bên trong letrunchặn.
Jacky Choi

6
achưa được xác định trong phạm vi của letrun. 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.
marstran

1
Mã nhanh hoàn thành việc gán atrước các khối mã đó. Và acó thể được truy cập vào bên trong.
Jacky Choi

1
Nó gán cho 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?
marstran

3
Bạn chỉ có thể truy cập 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.
marstran

51

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.


11

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
}

Sử dụng 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.
Marko Topolnik

6

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


Điều này chỉ hoạt động nếu b là một biến cục bộ. Còn các biến lớp thì sao?
Warpzit

5

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 1if-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  */

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  */

nhập mô tả hình ảnh ở đây

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.


4

Đâ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"
}

nếu tên == mã null trong {} không thực thi, nếu tên là Chuỗi - mã thực thi: nameUnwrapp == name.
Александр Яковенко

1
Tôi không nghĩ đây là những gì OP đang hỏi, tôi chắc chắn OP đã biết những gì 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.
kalehv

2

Đâ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.


0

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


1
Xin lưu ý rằng phương pháp bạn đang hiển thị hiện không biên dịch. Đây chỉ là một gợi ý về cách thay đổi ngôn ngữ Kotlin để giải quyết vấn đề này. Do đó, đây không phải là một giải pháp hợp lệ.
Peter F

0

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 }
}

-1

Tùy chọn sạch sẽ nhất theo ý kiến ​​của tôi là

Nhanh:

if let a = b.val {

} else {

}

Kotlin

b.val.also { a ->

} ?: run {

}

-1

Viết nhanh câu lệnh if let trong Kotlin

Câu trả lời ngắn gọn là sử dụng IF-ELSE đơn giản vì tại thời điểm nhận xét này không có nội dung tương đương trong Kotlin LET,

    if(A.isNull()){
// A is null
    }else{
// A is not null
    }
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.