当前位置: 首页 > 知识库问答 >
问题:

为什么这种类型需要显式强制转换?

何嘉运
2023-03-14

我为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时。

科特林难道不能自动执行这个智能演员阵容吗?

共有1个答案

余天宇
2023-03-14

刚想出来,新手犯了个错误。LocalDateTime类型参数只是一个别名。正确的声明是:

fun <S> TableColumn<S, LocalDateTime>.formatAsDateTime() =
    cellFormat { text = dateTimeFormatter.format(it) }
 类似资料: