2016-05-31 10 views
0

Ich versuche, etwas ähnlich wie diese Syntax in KotlinSo erstellen Sie Variablen auf Elternkontext

class MyClass() { 
    fun before(init:() -> Unit): Unit { 
     with(this) init 
    } 
    fun after(block:() -> Unit): Unit { 
     with(this) block 
    } 
} 

fun main() { 
    var myClass = MyClass() 
    myClass.before { 
     var a = 5 
    } 
    myClass.after { 
     println("Double of a is ${a * 2}") 
    } 
} 

Gerade jetzt implementieren wird dies nicht funktionieren, weil a nicht innerhalb after aufgelöst werden kann. Ich verstehe, dass dies auf die Funktionsweise der Schließungen zurückzuführen ist.

Meine Frage ist, ob es einen Mechanismus in Kotlin gibt, der es mir erlauben würde, Variablen in einer Schließung/Erweiterung so zu erstellen, dass sie im Empfängerobjekt gespeichert würden und für andere Schließungen/Erweiterungen zugänglich wären .

Dies ist Teil einer Bemühung, ein Groovy-Skript nach Kotlin zu migrieren.

Haftungsausschluss: Dies ist mein allererstes Los in Kotlin. Ich habe die Dokumentation gelesen, aber ich vermisse etwas (viel). Fühlen Sie sich frei, nur auf die richtige Richtung

EDIT Punkt: ist Hinzufügen übersetzbar Beispiel

class Aa() { 

    var a: Int = 0 
    var bb:() -> Unit = null!! 

    fun ww (block:() -> Unit) { 
     bb = block 
    } 

    fun doit(block:() -> Unit) { 
     with(bb) { 
      block() 
     } 
    } 

} 

fun main(args: Array<String>) { 
    val exec = fun Aa.(other:() -> Unit): Unit = other() 

    aa.ww { 
     var xx = 5 
    } 

    aa.doit { 
     // println("with $xx") <- this fails 
    } 
} 
+0

Im Gegensatz zu Groovy ist Kotlin eine statisch typisierte Sprache, was bedeutet, dass es nicht möglich ist, beliebige Werte in einem Objekt zu speichern, das nicht die Felder für diese Werte enthält. – yole

+0

@yole die Tatsache, dass Kotlin eine statisch typisierte Sprache ist, hat mich dazu veranlasst, in dieses Projekt einzutauchen. Ich habe mich gefragt, ob der Compiler schlau genug ist, diese Arten von Initialisierungen zu verstehen, aber ich nehme an, dass dies viel zu kompliziert wäre, besonders wenn Sie mit einer anderen Klasse/Funktion initialisieren und das Ergebnis woanders verwenden. – Hartimer

+0

Welche Art von Initialisierung soll das verstehen? Sie deklarieren eine Variable im Bereich einer anonymen Funktion, die an die Funktion "MyClass.before" übergeben wird. Sobald Sie die schließende Klammer drücken, wird dieser Bereich geschlossen und 'var a' existiert nicht mehr. –

Antwort

1

Kotlin eine statisch typisierte Sprache. Es ist nicht möglich, Daten innerhalb der Instanz eines Objekts zu speichern, für das in diesem Objekt kein Feld vorhanden ist.

Sie könnten eine Eigenschaft des Typs Map definieren und die Werte in dieser Map speichern, aber Sie können nicht mit der normalen Property-Syntax darauf zugreifen, sofern Sie nicht im Voraus wissen, welche Werte dort gespeichert werden.