Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

342
Views
Sobrecarga de función ambigua con covarianza de tipo pero no ambigua con genérico

Supongamos que tengo el siguiente código.

 open class Parent class Child: Parent() fun <T: Parent> foo(obj: T): T = obj inline fun <T: Parent> foo(block: () -> T): T = foo(block()) fun <T> bar(obj: T): T = obj inline fun <T> bar(block: () -> T): T = bar(block()) fun main() { /* Compile error: Overload resolution ambiguity. All these functions match. public inline fun <T : Parent> foo (block: () → TypeVariable(T)): TypeVariable(T) defined in examples in file example.kt public fun <T : Parent> foo (obj: TypeVariable(T)): TypeVariable(T) defined in examples in file example.kt */ foo { Child() } // Works bar { "something" } }

La primera llamada de función ( foo ) me da un error de compilación que dice que la resolución de sobrecarga es ambigua. Pero, ¿por qué es esto cierto si el bloque es de tipo () -> T y este no es un subtipo de Parent ?

¿No debería ocurrir este error en la segunda llamada de función ( bar )? ¿Por qué no ocurre?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Supongo que el problema aquí es con la inferencia de tipos. En cada uno de sus ejemplos, confía en la inferencia de tipos para dos cosas:

  1. Para determinar el valor del parámetro de tipo genérico T , y
  2. Para determinar la firma de la función lambda.

En el caso de foo , la resolución de la sobrecarga depende de conocer el valor del parámetro genérico T Eso es porque T está acotado. El valor real de T puede afectar si es válido llamar a este método o no, dependiendo de si T resulta ser un subtipo de Parent .

El problema es que T debe inferirse en función del valor del parámetro que se pasa, y el tipo de parámetro que se pasa debe inferirse en función de alguna información sobre qué sobrecarga se ha seleccionado y/o cuál es el valor de T es! Sospecho que esto crea una dependencia circular que evita que se complete la resolución de sobrecarga.

Puede solucionarlo proporcionando un valor para la firma lambda o para el parámetro de tipo genérico:

 foo<Parent> { Child() } // works foo({ Child() } as () -> Parent) // works

Extraer la lambda a una variable también lo soluciona, porque hace que el compilador infiera un tipo para la variable de inmediato:

 val lambda = { Child() } // type is inferred as () -> Child foo(lambda) // works, because lambda already has an inferred type

El problema no surge con la bar porque en ese caso, T no está acotado. No importa lo que T termine siendo, no afectará si se permite llamar o no a esa sobrecarga en particular. Eso significa que el compilador no necesita inferir un valor para T antes de realizar la resolución de sobrecarga.

over 4 years ago · Santiago Trujillo Report

0

Parece un error en el compilador (todavía presente en 1.6.0-M1).

Dos soluciones aquí:

  1. Especifique explícitamente el argumento de tipo:
 foo<Child> { Child() }

Irónicamente, hacer lo mismo con la parte de trabajo lo romperá (pero el error no será por ambigüedad, el compilador está bastante seguro de qué sobrecarga llamará: la incorrecta):

 /* Compile error: Type mismatch. Required: () → String Found: String */ bar<() -> String>({ "something" })
  1. Extraiga lambda en una variable separada:
 val lambda = { Child() } foo(lambda)

Esto arreglará la parte rota también:

 val block = { "something" } bar<() -> String>(block)
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!