我为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中应该发生什么。当当前单元格有非空项可用时更新项。例如,要格式化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.TemporalAccess!
诚然,DateTimeFormatter#format函数采用的是TemporalAccessor,而不是LocalDateTime,但LocalDateTime确实实现了TemporalAccessor(通过Temporal)。
只有在formatAsDateTime扩展函数中才需要转换为TemporalAccessor,而不是直接从调用站点使用cellFormat时。
科特林难道不能自动执行这个智能演员阵容吗?
刚想出来,新手犯了个错误。LocalDateTime类型参数只是一个别名。正确的声明是:
fun <S> TableColumn<S, LocalDateTime>.formatAsDateTime() =
cellFormat { text = dateTimeFormatter.format(it) }
我现在正在学习遗传和多态性,除此之外,我也理解它。为什么我需要投三个。setY()不应该已经可以访问它了,因为我正在创建一个从G类继承的H对象。 第8行是语法错误。
问题内容: 鉴于: 涉及并编译的语句很好,但是失败: 可以通过提供显式类型参数来解决编译器错误。 Java 8何时需要显式类型参数?意思是,是否存在一种打破类型推断的已知模式? 能和改变,以避免显式类型参数不失使用生成器的配置的收藏家? 更新 : 为什么涉及工作的陈述?它与所涉及的陈述有何不同? 问题答案: 要回答您的问题“意思是,是否存在一种已知的打破类型推断的模式?” 简短地说:当然,有一种模
鉴于: 涉及和的语句编译良好,但失败,原因如下: 编译器错误可以通过提供显式类型参数
无法编译以下内容: 特别是,使用javac编译时,错误将是: 但下面的汇编很好: 唯一的区别是我引入了一个额外的变量。请注意,我没有施法,所以没有语义变化。 有人能解释为什么需要这样做吗?