如何指定我不知道的类型参数

时间:2017-05-21 15:14:03

标签: generics kotlin

我已将问题减少到以下最小的演示:

interface Property<T : Comparable<T>>

fun <T : Comparable<T>> parsePropertyValue(property: Property<T>, value: String): T = TODO()

fun test() {
    val property: Property<*> = TODO()
    val value = parsePropertyValue(property, "test")
}

parsePropertyValue的调用无法编译,错误消息为&#34;无法推断类型参数T&#34;。等效的Java代码编译没有问题:

interface JavaProperty<T extends Comparable<T>> { }

class Test {

    public static void main(String[] args) {
        JavaProperty<?> property = null;
        Comparable<?> value = parsePropertyValue(property, "test")
    }

    private static <T extends Comparable<T>> T parsePropertyValue(JavaProperty<T> property, String value) {
        return null;
    }

}

如何在Kotlin中实现类似的功能?请注意,此示例中的Property接口来自外部库,我无法更改它。

根据要求,一个更大的例子:

interface Property<T : Comparable<T>> {
    fun parseValue(value: String): T
}

interface PropertyStore {
    fun <T : Comparable<T>> setValue(property: Property<T>, value: T)
    fun <T : Comparable<T>> getValue(property: Property<T>): T
}

fun main() {
    val property: Property<*> = TODO()
    val unparsedValue: String = TODO()
    val propertyStore: PropertyStore = TODO() 
}

fun <T : Comparable<T>> parseAndApplyValue(propertyStore: PropertyStore, property: Property<T>, unparsedValue: String) {
    val parsedValue: T = property.parseValue(unparsedValue)
    propertyStore.setValue(property, parsedValue)
}

2 个答案:

答案 0 :(得分:0)

它没有编译的原因是因为class B val a: A = A() if (a is A) { /* do something */ } when (a) { someValue -> { /* do something */ } is B -> { /* do something */ } else -> { /* do something */ } } 必须通过PropertyComparable的参与来进行参数化。

你有可能改变

*

val property: Property<*> = TODO()

或其他val property: Property<Int> = TODO()?这将使您的代码编译。

答案 1 :(得分:0)

虽然在错误的地方,IntelliJ IDEA正在暗示你的答案:

enter image description here

注意灰色下划线?这是一个检查,告诉你添加'in'方差修饰符:

enter image description here

将代码更改为interface Property<in T : Comparable<T>>后,所有内容都会编译。

您可以在此处详细了解差异:http://kotlinlang.org/docs/reference/generics.html