string - check - let kotlin null
¿Por qué el tipo de nulo+nulo implícitamente String en Kotlin? (3)
El siguiente código de Kotlin:
val x = null + null
los resultados en x
son de tipo String
, lo cual es correcto de acuerdo con los documentos para String.plus
:
Concatena esta cadena con la representación de cadena del objeto [otro] dado. Si el receptor o el objeto [otro] son nulos, se representan como la cadena "nula".
Sin embargo, no entiendo por qué sucede esto, ¿se debe a alguna característica especial del idioma?
Necesitamos comenzar con el tipo de Nothing
. Este tipo tiene exactamente cero valores posibles. Es un tipo de fondo , y es un subtipo de cualquier otro tipo (no debe confundirse con Any
, que es un supertipo de cualquier otro tipo ). Nothing
se puede coaccionar a ningún tipo, por lo que puedes hacer cosas como:
fun doStuff(a: Int): String =
TODO("this typechecks")
Pasando al tipo de Nothing?
, significando Nothing
o null
. Tiene 0 + 1 valores posibles. ¿Así que null
tiene un tipo de Nothing?
. Nothing?
se puede obligar a cualquier tipo de nullable, para que pueda hacer cosas como:
var name: String? = null
Aquí null : Nothing?
es obligado a la String?
.
Por alguna razón, desafortunadamente, hay String.plus :
operator fun String?.plus(other: Any?): String
eso permite null + null
aprovechando esas reglas de coerción que mencioné anteriormente
Probablemente porque String?.plus(Any?)
Es la única función String?.plus(Any?)
que acepta un tipo anulable como receptor en la biblioteca Kotlin. Por lo tanto, cuando llamas null + null
, el compilador tratará el primer null
como String?
.
Si define una función de extensión donde el tipo de receptor es Int?
y el tipo de retorno es Int
, entonces x
se inferirá como Int
.
public operator fun Int?.plus(other: Any?): Int = 1
val x = null + null
Si declara otra función similar dentro del mismo archivo (tipo anulable que el tipo de receptor), cuando llama a null + null
, se produce el error de tiempo de compilación: Overload resolution ambiguity. All these functions match.
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
val x = null + null
Intenta reformular esto de la siguiente manera y encontrarás tu respuesta:
val x = null.plus(null)
A continuación se muestra lo que muestra IntelliJ como la firma del método plus
:
public operator fun String?.plus(other: Any?): String
¿Entonces el primer null
es tratado como String?
escriba y luego, cuando intente hacer algo más, el único método anterior es la única coincidencia que tiene. Imprimiendo x
resultará en nullnull