【问题标题】:Why does this type need explicit cast?为什么这种类型需要显式转换?
【发布时间】: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


    【解决方案1】:

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

    fun <S> TableColumn<S, LocalDateTime>.formatAsDateTime() =
        cellFormat { text = dateTimeFormatter.format(it) }
    

    【讨论】:

    • 编译器不应该抱怨类型参数遮蔽了LocalDateTime吗?
    • 不会,但我认为 Java 中也不会发生这种情况。我的班级甚至没有 java.time.LocalDateTime 的导入,所以编译器真的不可能知道这一点。但是,即使导入它也不会抱怨。
    • 您是否愿意为此类警告填写功能请求?它可以为某人节省很多时间
    • 我在想,这一定是有原因的,为什么这还没有在 javac 中实现。大多数时候,您可能没有导入,所以我认为用例非常少。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多