Kotlin: Confusión con lambdas y generics

Por favor vea los posts de error en los comentarios:

interface Printable {} class Book(val title: String) :Printable fun bookPrint(b: Book?):String = "Title: " + b?.title class Author(val name: String) :Printable fun authorPrint(a: Author?):String = "Name: " + a?.name // Unsupported: [modifier on parameter in function type] // -------------vv fun printIt(f: (in Printable?) -> String, a:Printable):String { return "Unknown: " + f.invoke(null) + "Known: " + f.invoke(a) } fun main(args: Array<String>) { // Type Mismatch: // Requinetworking: (Printable?) -> String // Found: KFunction1<Book?,String> // -------vvvvvvvvv printIt(::bookPrint, Book("Storm Front")) // -------vvvvvvvvvvv printIt(::authorPrint, Author("Jim Butcher")) } 

Puntos key:

  • bookPrint() y authorPrint() ambos necesitan tomar un libro nulo / autor
  • printIt() necesita tomar cualquiera de esas funciones.

Entonces, pensando "productor-extiende, consumidor-súper", creo que mi problema es que quiero que un parámetro de input sea covariante, cuando está codificado de forma rígida para ser contravariante ("en").

Tuve esta idea que no funcionó:

 // Unresolved reference: KFunction1 // --------------vvvvvvvvvv fun htmlList2(f: KFunction1<Printable?,String>, a:Printable):String { return "Unknown: " + f.invoke(null) + "Known: " + f.invoke(a) } 

Creo que esto es correcto:

 interface Printable {} class Book(val title: String) :Printable fun bookPrint(b: Book?):String = "Title: " + b?.title class Author(val name: String) :Printable fun authorPrint(a: Author?):String = "Name: " + a?.name // Add type parameter T, upper-bounded by Printable. This ties // the type of the first argument to the type of the second and // ensures they are both Printable. fun <T:Printable> printIt(f: (T?) -> String, a:T):String { return "Unknown: " + f.invoke(null) + "Known: " + f.invoke(a) } fun main(args: Array<String>) { printIt(::bookPrint, Book("Storm Front")) printIt(::authorPrint, Author("Jim Butcher")) } 

Gracias a experimentar y leer la documentation sobre restricciones genéricas: Upper Bounds

Todavía interesado si hay una mejor manera …