2017-06-17 14 views
4

は、私はこのようなSharedPreferencesから値を取得するための簡単なヘルパー機能を持つクラスを使用します。Kotlin - reified型パラメータとして 'T'を使用できません。代わりに

私はクラス型の切り換え持つように具体化タイプのパラメータを使用していると、それはオペレータの関数であるので、私はあるべき
operator inline fun <reified T : Any> SharedPreferences.get(key: String, defaultValue: T? = null): T? { 
    return when (T::class) { 
     String::class -> getString(key, defaultValue as? String) as T? 
     Int::class -> getInt(key, defaultValue as? Int ?: -1) as T? 
     Boolean::class -> getBoolean(key, defaultValue as? Boolean ?: false) as T? 
     Float::class -> getFloat(key, defaultValue as? Float ?: -1f) as T? 
     Long::class -> getLong(key, defaultValue as? Long ?: -1) as T? 
     else -> throw UnsupportedOperationException("Not yet implemented") 
    } 
} 

以下のような角括弧構文で呼び出すことができ:

val name: String? = prefs[Constants.PREF_NAME] 

しかし、私はそれを呼び出すたびに、UnsupportedOperationExceptionが関数がクラス型を取得することができないかを示すスローされます。私は、デバッガをアタッチし、T::classを評価するとき

、私の機能と間違って何"Cannot use 'T' as reified type parameter. Use a class instead."

私にエラーを与えていますか?私は間違いをキャッチできませんでした。誰も助けることができますか?

編集:クラス全体がherethis is whereです。エラーが発生します。

更新:これはKotlinコンパイラの問題です。 トラックhttps://youtrack.jetbrains.com/issue/KT-17748および https://youtrack.jetbrains.com/issue/KT-17748を更新してください。

+0

私はあなたのエラーを再現することはできません。私が気づくことの1つは、 'when'の結果を返さないということです。常にnullを返します。 –

+0

@JornVerneeあなたはこれを見てください:https://gist.github.com/krupalshah/782c42c70f2c58004c9bbda6291315e6私はあなたの助けが必要です。 –

+0

エラーを再現できない場合はお手伝いできません。 –

答えて

2

問題は不思議ですが、はInt?::class(これは不正な表現です)と同じではないようです。あなたが行を追加すると

get方法に

println(T::class) 

を、そしてval age: Int? = prefs["AGE", 23]を呼び出し、あなたはそれがjava.lang.Integerを印刷していることがわかります。

Int?java.lang.Integerに翻訳されているようです。

可能(ただし、私見ハックの一種)溶液のための例として、Javaクラスへの参照を使用することです:

operator inline fun <reified T : Any> get(key: String, defaultValue: T? = null): T? { 
    return when (T::class) { 
     String::class -> getString(key, defaultValue as? String) as T? 
     java.lang.Integer::class -> getInt(key, defaultValue as? Int ?: -1) as T? 
     java.lang.Boolean::class -> getBoolean(key, defaultValue as? Boolean ?: false) as T? 
     java.lang.Float::class -> getFloat(key, defaultValue as? Float ?: -1f) as T? 
     java.lang.Long::class -> getLong(key, defaultValue as? Long ?: -1) as T? 
     else -> throw UnsupportedOperationException("Not yet implemented") 
    } 
} 
+0

ありがとうございます。あなたが正しいです。最初の解決策も今はうまくいきます。 Kotlinコンパイラの新しいバグを発見しましたか? –

+1

@KrupalShahバグではなく、欠点かもしれません。それは 'java.lang.Integer :: class'を' Int :: class'と比較すると特別な扱いがありません –

+0

Hm .. ok。あなたの2番目のソリューションは問題ありませんが、唯一の問題は、文字列が必要な場合でもnullをデフォルト値として渡すことができるということです。その時はうまくいきません。 –

関連する問題