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

时间:2015-11-28 20:36:00

标签: java generics casting kotlin

我已经为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不应该自动执行这个智能演员吗?

1 个答案:

答案 0 :(得分:2)

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

Frame.Navigate(typeof(RegisterPage)));