2016-10-01 83 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的答案中那樣 - 我懷疑這個問題的確是同一個問題 –