2017-05-25 6 views
10

Ich habe die folgenden einfachen Kotlin Erweiterungsfunktionen „Typen Parameter einer Eigenschaft muss in seinem Empfängertyp verwendet werden“:Kotlin Eigentum:

// Get the views of ViewGroup 
inline val ViewGroup.views: List<View> 
    get() = (0..childCount - 1).map { getChildAt(it) } 

// Get the views of ViewGroup of given type 
inline fun <reified T : View> ViewGroup.getViewsOfType() : List<T> { 
    return this.views.filterIsInstance<T>() 
} 

Dieser Code kompiliert und funktioniert einwandfrei. Aber ich möchte die Funktion getViewsOfType eine Eigenschaft sein, genau wie die views. Android Studio schlägt es sogar vor. Ich lasse AS tun das Refactoring und erzeugt diesen Code:

inline val <reified T : View> ViewGroup.viewsOfType: List<T> 
    get() = this.views.filterIsInstance<T>() 

Aber dieser Code nicht kompiliert. Es verursacht Fehler: "Typ-Parameter einer Eigenschaft muss in seinem Empfängertyp verwendet werden"

Was ist das Problem hier? Suchen nach Hilfe zu diesem Fehler scheint nicht zu einer Antwort zu führen.

Antwort

10

Der Fehler bedeutet, dass Sie nur einen generischen Typparameter für eine Erweiterungseigenschaft haben können, wenn Sie diesen Typ im Empfängertyp verwenden - den Typ, den Sie erweitern.

Zum Beispiel könnten Sie eine Erweiterung haben, die sich T:

val <T: View> T.propName: Unit 
    get() = Unit 

Oder eine, die eine Art erstreckt, T als Parameter verwendet:

val <T: View> List<T>.propName: Unit 
    get() = Unit 

Was, warum diese ist, ich denke der Grund ist, dass eine Eigenschaft keinen generischen Typparameter wie eine Funktion haben kann. Während wir eine Funktion mit einem generischen Typparameter aufrufen können ...

val buttons = viewGroup.getViewsOfType<Button>() 

... Ich glaube nicht, eine ähnliche Syntax für Eigenschaften existiert:

val buttons = viewGroup.viewsOfType<Button> // ?? 
+0

Ja, ich denke, das ist richtig. Tatsächlich ist meine "getViewOfType" -Funktion nutzlos, da Kotlin bereits über eine Möglichkeit verfügt, die Auflistung nach Typ zu filtern. –