【发布时间】:2015-11-28 20:35:59
【问题描述】:
我已经为 JavaFX TableColumn 创建了一个扩展函数,它使得在没有重复样板的情况下实现 cellFactory 变得更加简洁。扩展函数定义如下:
inline fun <S, T> TableColumn<S, T>.cellFormat(crossinline formatter: (TableCell<S, T>.(T) -> Unit)) {
cellFactory = Callback { column: TableColumn<S, T> ->
object : TableCell<S, T>() {
override fun updateItem(item: T, empty: Boolean) {
super.updateItem(item, empty)
if (item == null || empty) {
text = null
graphic = null
} else {
formatter(this, item)
}
}
}
}
}
要格式化 TableCell,我只需要定义 TableCell.updateItem 当当前单元格有可用的非空项时应该发生什么。例如,要格式化 LocalDateTime,我现在可以这样写:
column.cellFormat { text = DateTimeFormatter.ISO_DATE_TIME.format(it) }
然后我继续定义另一个扩展来做这个,所以我可以写:
column.formatAsDateTime()
这个函数使用第一个函数,像这样:
fun <S, LocalDateTime> TableColumn<S, LocalDateTime>.formatAsDateTime() =
cellFormat { value ->
text = DateTimeFormatter.ISO_DATE_TIME.format(value as TemporalAccessor)
}
我的问题是为什么我必须将 LocalDateTime 转换为 TemporalAccessor?
我的第一次尝试是:
text = DateTimeFormatter.ISO_DATE_TIME.format(value)
编译器抱怨:
类型不匹配:推断类型是 LocalDateTime 但 java.time.TemporalAccessor!预料之中
当然,DateTimeFormatter#format 函数采用 TemporalAccessor,而不是 LocalDateTime,但 LocalDateTime 确实实现了 TemporalAccessor(通过 Temporal)。
仅在 formatAsDateTime 扩展函数中需要转换为 TemporalAccessor,而不是在直接从调用站点使用 cellFormat 时。
Kotlin 不应该能够自动执行这种智能转换吗?
【问题讨论】:
标签: java generics casting kotlin