Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

407
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda