给定以下方法扩展(JsonResult只是一个带有一些附加字段的包装器):
fun <T, R> T.toJson(transform: (T) -> R) = JsonResult(transform(this))
fun <T, R> List<T>.toJson(transform: (T) -> R) = JsonResult(this.map(transform))
fun <T, R> Page<T>.toJson(transform: (T) -> R) = JsonResult(this.content.map(transform)
当我尝试从列表或不是列表的对象调用上述任何方法时,我得到编译器错误,其中包含我期望的消息Cannot choose among the following candidates without completing type inference
import org.springframework.data.domain.Page
val person = Person()
person.toJson { } // compiler error
val people = List<Person>()
people.toJson { } // compiler error
val pageablePeople = Page<Person>
pageablePeople.toJson { }
我想知道是否有其他(惯用?)方式来声明这些函数而不更改其名称。
答案 0 :(得分:0)
您遇到重载解析错误的原因是因为List<T>
类型的接收方与fun <T, R> T.toJson
和fun <T, R> List<T>.toJson
都匹配。
带有未绑定接收器的扩展功能可能会出现问题,因为它们会出现在每个自动完成建议中,因为它们始终是重载解析的候选者。
我建议将未绑定版本设为顶级版本或将其置于object
。
示例:
fun <T, R> toJson(t: T, transform: (T) -> R) = JsonResult(transform(t))
fun <T, R> List<T>.toJson(transform: (T) -> R) = JsonResult(map(transform))
fun <T, R> Page<T>.toJson(transform: (T) -> R) = JsonResult(content.map(transform))
fun main(args: Array<String>) {
val person = Person()
toJson(person) {}
val people = listOf<Person>()
people.toJson { }
val pageablePeople = Page<Person>()
pageablePeople.toJson { }
}
此外,对于您可以控制的类,您可以使toJson
实例函数在重载决策中始终赢得扩展函数。
class Page<T>(val content: List<T>) {
fun <R> toJson(transform: (T) -> R) = JsonResult(content.map(transform))
}