2017-11-07 71 views
26

Mã Kotlin sau:Tại sao loại null null vô hạn trong Kotlin?

val x = null + null 

kết quả trong x phúc lợi của loại String, đó là chính xác như theo các tài liệu cho String.plus:

Concatenates this string with the string representation of the given [other] object. If either the receiver or the [other] object are null, they are represented as the string "null".

Tuy nhiên, tôi không hiểu tại sao điều này xảy ra - là do một số tính năng đặc biệt của ngôn ngữ?

+1

Có một câu hỏi ở đây? Blockquote giải thích tại sao x là một chuỗi. –

+0

@MartinJoiner cho tôi nó vẫn còn lạ rằng tham số đầu tiên 'null' là chuỗi. – Morozov

+5

Vui lòng cung cấp tham chiếu cho báo giá –

Trả lời

40

Có thể vì String?.plus(Any?) là hàm plus duy nhất chấp nhận loại có thể vô hiệu hóa làm người nhận trong thư viện Kotlin. Do đó, khi bạn gọi null + null, trình biên dịch sẽ xử lý null đầu tiên là String?.

Nếu bạn xác định một chức năng mở rộng nơi các loại máy thu là Int? và kiểu trả về là Int, sau đó x sẽ được suy ra như Int.

public operator fun Int?.plus(other: Any?): Int = 1 
val x = null + null 

Nếu bạn khai báo một chức năng tương tự trong cùng một tập tin (loại nullable như các loại máy thu), khi bạn gọi null + null, nó gây ra các lỗi thời gian biên dịch: Overload resolution ambiguity. All these functions match..

public operator fun Int?.plus(other: Any?): Int = 1 
public operator fun Float?.plus(other: Any?): Float = 1F 
val x = null + null //compile time error 
4
val x = null + null 

Cố gắng nói lại điều này như dưới đây và bạn sẽ tìm thấy bạn trả lời:

val x = null.plus(null) 

dưới đây là những gì IntelliJ thấy như chữ ký của phương pháp plus:

public operator fun String?.plus(other: Any?): String 

Vì vậy, null đầu tiên được coi là loại String? và sau đó khi y Ngoài ra, phương pháp plus ở trên là kết quả duy nhất bạn có. In ra x sẽ dẫn đến nullnull

4

Chúng tôi cần bắt đầu với loại Nothing. Loại này có chính xác giá trị có thể bằng 0. Đó là bottom type và là loại phụ của mọi loại khác (không bị nhầm lẫn với Any, là supertype of every other type). Nothing thể buộc bất kỳ loại, do đó bạn có thể làm những thứ như:

fun doStuff(a: Int): String = 
    TODO("this typechecks") 

Chuyển sang loại Nothing?, có nghĩa Nothing hoặc null. Nó có 0 + 1 giá trị có thể. Vì vậy, null có một loại Nothing?. Nothing? thể buộc bất kỳ loại nullable, vì vậy mà bạn có thể làm công cụ như:

var name: String? = null 

Đây null : Nothing? được cưỡng chế thi hành String?.

Đối với một số lý do, không may, có this function defined in stdlib:

operator fun String?.plus(other: Any?): String 

cho phép null + null tận dụng những quy tắc ép buộc tôi đã đề cập ở trên

+2

Tôi nhận được sự rung cảm của js –

Các vấn đề liên quan