Kotlin:与lambda和泛型混淆

请在评论中看到错误信息:

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: // Required: (Printable?) -> String // Found: KFunction1<Book?,String> // -------vvvvvvvvv printIt(::bookPrint, Book("Storm Front")) // -------vvvvvvvvvvv printIt(::authorPrint, Author("Jim Butcher")) } 

关键点:

  • bookPrint()authorPrint()都需要一个空书/作者
  • printIt()需要采取这些功能之一。

所以,思考“生产者扩展,消费者超级”我认为我的问题是我想要一个输入参数是协变的,当它被硬编码为逆变(“in”)时。

我有这个想法不起作用:

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

我认为这是正确的:

 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")) } 

感谢您试验和阅读关于通用约束:上界的文档

如果有更好的方法仍然感兴趣…