Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

401
Vistas
Extension method, when called on a null object, is called on the wrong type
fun main() {
    val set: Set<Int>?
    set = null
    val emptySet: Set<Int> = set.orEmpty()
}

Can't figure out why even when explicitly typing the set variable as Set <Int>? the compiler considers that in the extension method set.orEmpty () set - is a string and, accordingly, crashes with an error:

Kotlin: Type mismatch: inferred type is String but Set was expected

But when declaring and initializing in one line, everything happens correctly:

fun main() {
    val set: Set<Int>? = null
    val emptySet: Set<Int> = set.orEmpty()
}
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

The behavior you're observing can be explained by the interaction of two Kotlin features:

  • first, the type of set variable is narrowed to Nothing? as a result of a smart cast after the assignment of null value to it. The smart cast after an assignment can be useful in cases when it narrows variable type to a more specific type, but narrowing to Nothing? does more harm than good.
  • second, among all overloads of orEmpty function available for a value of type Nothing?, the non-generic one String?.orEmpty() is chosen due to the specific rule of Kotlin overload resolution: a non-generic candidate is preferred to generic ones.

This behavior indeed can be puzzling, so I've reported this problem as KT-50661.

over 4 years ago · Santiago Trujillo Denunciar

0

I think this is related to the fact that the compiler is not so smart that it could deduce that the code set = null will be executed exactly once – it could be zero times or more than once.

If you know that it will run exactly one, you can tell the compiler by using a feature called kotlin.contracts:

import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

@ExperimentalContracts
fun main() {
  val set: Set<Int>?
  once { set = null }
  val emptySet: Set<Int> = set.orEmpty()
}

@ExperimentalContracts
fun once(lambda: () -> Unit) {
  contract { callsInPlace(lambda, InvocationKind.EXACTLY_ONCE) }
  lambda()
}

See https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.contracts/

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda