2016-10-16 7 views
3

を取得し、あなたがこのようなパッケージの拡張プロパティのKPropertyを取得するには、参照演算子を使用することができます。kotlinでは、非パッケージの拡張プロパティのKProperty

val String.extProp: String 
    get() = "Some get code" 

fun foo() { 
    val prop: KProperty<String> = String::extProp 
} 

ただし、拡張プロパティが内で宣言されたときクラス参照演算子は、もはや機能していない:

class Example() { 

    val String.extProp: String 
     get() = "Some get code" 

    fun foo() { 
     val prop: KProperty<String> = String::extProp // error 
    } 

} 

だから私はKPropertyを得ているので、私は、第二の例では、問題の行を変更することができますどのようにされて疑問に思って何?

答えて

5

あなたが取得しているエラーは、次のとおりです。

Error:(y, x) Kotlin: 'extProp' is a member and an extension at the same time. References to such elements are not allowed

も含むクラスを必要とする拡張メソッドへの参照を生成する何の構文メカニズムはありません。たとえば、あなたの内線番号はクラスのメンバーを使用するかもしれません。これはKotlin 1.1に入ってくる "bound references"のようなものを必要とします(このケースをカバーするかどうかは現在はopen questionです)。今のところ、はありません。::構文があります。 Example::String::extPropのようなものはではなく、が利用可能であり、どちらも一般的に試されたExample::String.extPropの構文ではありません。しかし、それを反映して見つけることができます。

まずあなたが知っている必要がありますあなたが受け取るタイプがある:

KProperty2<INSTANCE, EXTENDING, PROPTYPE> 

クラスの通常のプロパティであるのに対し:

KProperty1<INSTANCE, PROPTYPE> 

は、あなたが知っている必要があり、そのいずれかの呼び出しにあるためgetterには、クラスインスタンスと、プロパティが拡張しているクラスのインスタンスが必要です。したがって、クラスのプロパティ参照と同じ方法で呼び出すことはできません。これは、チェックのためのビットやり過ぎですが、それは、拡張子の他の種類がある場合は将来性があることを保証

@Suppress("UNCHECKED_CAST") 
fun <T: Any, EXTENDING: Any, R: Any> KClass<T>.extProp(extends: KClass<EXTENDING>, name: String, returning: KClass<R>): KProperty2<T, EXTENDING, R> { 
    return this.declaredMemberExtensionProperties.first { 
     it.name == name && 
       it.parameters.size == 2 && 
       it.parameters[0].kind == KParameter.Kind.INSTANCE && it.parameters[0].type == this.defaultType && 
       it.parameters[1].kind == KParameter.Kind.EXTENSION_RECEIVER && it.parameters[1].type == extends.defaultType && 
       it.returnType == returning.defaultType 
    } as KProperty2<T, EXTENDING, R> 
} 

あなたはクラスで宣言拡張プロパティを見つけるために、この機能を使用することができます後で追加。それを使用するようにコードが更新されました:

class Example() { 
    val String.extProp: String 
     get() = "howdy $this" 

    fun foo() { 
     val prop = Example::class.extProp(String::class, "extProp", String::class) 
     println(prop.get(this, "stringy")) // "howdy stringy" 
    } 
} 
関連する問題