Toán tử Double-bang (!!) của Kotlin là gì?


177

Tôi đang chuyển đổi Java sang Kotlin với Android Studio. Tôi nhận được gấp đôi sau khi biến thể hiện. Double bang là gì và quan trọng hơn là tài liệu này ở đâu?

mMap!!.addMarker(MarkerOptions().position(london).title("Marker in London"))

Câu trả lời:


205

Đây là T?chuyển đổi loại nullable ( ) không an toàn thành loại không nullable ( T), !!sẽ ném NullPointerExceptionnếu giá trị là null.

Nó được ghi lại ở đây cùng với phương tiện an toàn vô hiệu của Kotlin.


1
có nghĩa là gì khi !!phần cuối của một tuyên bố? IJ tự động chuyển đổi sang Kotlin đã làm điều đó cho tôival price = sale.latest!!
ycomp 23/2/2016

7
@ycomp, có nghĩa là sale.latestcó thể chứa null; nhiệm vụ sẽ chỉ thành công nếu sale.latestkhông phải là null và sẽ ném NPE theo cách khác. Điều này mang lại sự an toàn cho null val price: loại của nó sẽ không null. Xem kotlinlang.org/docs/reference/null-safe.html
hotkey

1
@hotkey: Vậy sự khác biệt giữa việc nhận NPE - ở đây HOẶC khi phương thức mới nhất được truy cập trên đối tượng null là gì?
Aada

2
@Aada, vấn đề phổ biến là gỡ lỗi NPE và gặp khó khăn trong việc định vị đường dẫn / đường thực thi đặt giá trị thành null. Việc chuyển nhượng null này có thể xảy ra trên một bối cảnh, lớp học hoặc thậm chí cả ngày khác! Bằng cách sử dụng, !!bạn có thể không nhanh và xác định nguyên nhân gốc của NPE. Tôi ước Java có một tính năng tương tự (đó là, các ifcâu lệnh và / hoặc assertcác ion xấu xí ).
Cascader

82

Dưới đây là một ví dụ để làm cho mọi thứ rõ ràng hơn. Nói rằng bạn có chức năng này

fun main(args: Array<String>) {
    var email: String
    email = null
    println(email)
}

Điều này sẽ tạo ra lỗi biên dịch sau.

Null can not be a value of a non-null type String

Bây giờ bạn có thể ngăn chặn điều đó bằng cách thêm một dấu hỏi vào Stringloại để làm cho nó không có giá trị.

Vì vậy chúng tôi có

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email)
}

Điều này tạo ra kết quả của

null

Bây giờ nếu chúng ta muốn hàm ném một ngoại lệ khi giá trị của email là null, chúng ta có thể thêm hai dấu chấm than ở cuối email. Như thế này

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email!!)
}

Điều này sẽ ném một KotlinNullPointerException


5
Vậy, tại sao mọi người sẽ sử dụng '!!' mặc dù nó không an toàn vì một ứng dụng sẽ bị chấm dứt khi biến đó có null?
Sam

3
@david bạn chỉ có thể sử dụng nó khi bạn chắc chắn 100% rằng biến đó không phải là null (ví dụ: bạn đã kiểm tra rõ ràng) và bạn cần biến không nullable
FMK

7
@FMK Tôi hiểu rồi, cảm ơn! Tôi hiểu rằng double bang được sử dụng để làm cho các giá trị của biến loại nullable có thể đi vào biến loại không nullable, phải không?
Sam

2
@david vâng, chính xác.
FMK

10

Toán tử Double-bang là một lựa chọn tuyệt vời cho người hâm mộ NullPointerException(hoặc viết tắt là NPE).

Các nhà điều hành khẳng định không null !! chuyển đổi bất kỳ giá trị cho một loại không null và ném một ngoại lệ nếu giá trị là null.

val nonNull = a!!.length

Vì vậy, bạn có thể viết a!!và điều này sẽ trả về giá trị khác không a( Stringví dụ ở đây) hoặc ném NPE nếua là null.

Nếu bạn muốn có một NPE, bạn có thể có nó, nhưng bạn phải yêu cầu nó một cách rõ ràng. Toán tử này nên được sử dụng trong trường hợp nhà phát triển đảm bảo - giá trị sẽ không bao giờ là null .


2
Hỏi khi mới bắt đầu: tại sao tôi muốn chuyển đổi bất kỳ giá trị nào thành loại không null?
Wolf359

4
@ Wolf359 Nó cho phép bạn chắc chắn 100% rằng giá trị của nó không phải là null. ("Đây là vấn đề phổ biến để gỡ lỗi NPE và gặp khó khăn trong việc định vị đường dẫn / thực thi đặt giá trị thành null. Việc gán null này có thể xảy ra trên một bối cảnh, lớp hoặc thậm chí cả ngày khác!" của Cascader)
giảm hoạt động
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.