2016-10-01 78 views
2

我想写类似如何链接两个Kotlin函数参数的泛型?

fun <T, R> check(thing: T, property: KProperty1<T, R>, value: R) = 
    property.get(thing) == value 

使

assertTrue(check("Hello", String::length, 5)) 

assertTrue(check("Hello", String::length, "banana")) 

不能编译。

+2

相关http://stackoverflow.com/q/39596420/97777 –

回答

3

这似乎是Kotlin类型推理的一个问题(不管它是一个bug还是设计,我不知道)。例如,如果类型是明确的,这并不编译:

check<String, Int>("Hello", String::length, "banana") 

它可能是设计为类似Java的泛型方法的类型推断,这使得这个工作,因为编译器推断一个共同的超类型的RT两个参数。见Why doesn't type argument inference fail when I provide inconsistent method arguments?

根据上述职位,在Java 5,6,7,你很可能宣布它像

fun <T, R, R1: R> check(thing: T, property: KProperty1<T, R>, value: R1) = 
    property.get(thing) == value 

和不一致PARAMS,呼叫不能编译(我还没有尝试过) 。但是,这被认为是一个错误,在Java 8中,调用不一致的参数仍然会编译(我尝试过)。

在任何情况下,你可以在一个类包裹,避免了推理和领带的类型参数一起:

class Checker<T, R>(val property: KProperty1<T, R>) { 
    fun check(thing: T, value: R) = 
    property.get(thing) == value 
} 
assertTrue(Checker(String::length).check("Hello", 5)) 
// does not compile 
assertTrue(Checker(String::length).check("Hello", "banana")) 
+0

我不认为这是一个错误 - 我的函数的泛型类型满足任何,所以它编译。您引用中引用的Array.fill示例也在Kotin Generics文档中引用,但我尝试使用使用站点差异失败。 –

+0

我想我们可以在方法调用后面隐藏类型编组对象的创建,就像在http://stackoverflow.com/q/39596420/97777的答案中那样 - 我怀疑这个问题的确是同一个问题 –