Scala Language
Dynamischer Aufruf
Suche…
Einführung
Mit Scala können Sie dynamisches Aufrufen verwenden, wenn Sie Methoden aufrufen oder auf Felder eines Objekts zugreifen. Anstatt diese tief in die Sprache zu integrieren, wird dies durch Umschreiben von Regeln erreicht, die denen impliziter Konvertierungen ähnlich sind, die durch das Merkmalsmerkmal [
scala.Dynamic
] [Dynamic scaladoc] ermöglicht werden. Auf diese Weise können Sie die Fähigkeit zum dynamischen Hinzufügen von Eigenschaften zu Objekten in dynamischen Sprachen usw. emulieren. [Dynamic scaladoc]: http://www.scala-lang.org/api/2.12.x/scala/Dynamic.html
Syntax
- Klasse Foo erweitert Dynamic
- foo.field
- foo.field = Wert
- foo.method (args)
- foo.method (namedArg = x, y)
Bemerkungen
Um Subtypen zu erklären Dynamic
, die Sprache - Funktion dynamics
muss aktiviert werden, entweder durch den Import scala.language.dynamics
oder durch die -language:dynamics
- Compiler - Option. Benutzer dieses Dynamic
, die keine eigenen Subtypen definieren, müssen dies nicht aktivieren.
Feldzugriffe
Diese:
class Foo extends Dynamic {
// Expressions are only rewritten to use Dynamic if they are not already valid
// Therefore foo.realField will not use select/updateDynamic
var realField: Int = 5
// Called for expressions of the type foo.field
def selectDynamic(fieldName: String) = ???
def updateDynamic(fieldName: String)(value: Int) = ???
}
ermöglicht den einfachen Zugriff auf Felder:
val foo: Foo = ???
foo.realField // Does NOT use Dynamic; accesses the actual field
foo.realField = 10 // Actual field access here too
foo.unrealField // Becomes foo.selectDynamic(unrealField)
foo.field = 10 // Becomes foo.updateDynamic("field")(10)
foo.field = "10" // Does not compile; "10" is not an Int.
foo.x() // Does not compile; Foo does not define applyDynamic, which is used for methods.
foo.x.apply() // DOES compile, as Nothing is a subtype of () => Any
// Remember, the compiler is still doing static type checks, it just has one more way to
// "recover" and rewrite otherwise invalid code now.
Methodenaufrufe
Diese:
class Villain(val minions: Map[String, Minion]) extends Dynamic {
def applyDynamic(name: String)(jobs: Task*) = jobs.foreach(minions(name).do)
def applyDynamicNamed(name: String)(jobs: (String, Task)*) = jobs.foreach {
// If a parameter does not have a name, and is simply given, the name passed as ""
case ("", task) => minions(name).do(task)
case (subsys, task) => minions(name).subsystems(subsys).do(task)
}
}
erlaubt Aufrufe von Methoden mit und ohne benannte Parameter:
val gru: Villain = ???
gru.blu() // Becomes gru.applyDynamic("blu")()
// Becomes gru.applyDynamicNamed("stu")(("fooer", ???), ("boomer", ???), ("", ???),
// ("computer breaker", ???), ("fooer", ???))
// Note how the `???` without a name is given the name ""
// Note how both occurrences of `fooer` are passed to the method
gru.stu(fooer = ???, boomer = ???, ???, `computer breaker` = ???, fooer = ???)
gru.ERR("a") // Somehow, scalac thinks "a" is not a Task, though it clearly is (it isn't)
Interaktion zwischen Feldzugriff und Aktualisierungsmethode
Etwas uninteressant (aber auch der einzige vernünftige Weg, damit es funktioniert):
val dyn: Dynamic = ???
dyn.x(y) = z
ist äquivalent zu:
dyn.selectDynamic("x").update(y, z)
während
dyn.x(y)
ist immer noch
dyn.applyDynamic("x")(y)
Es ist wichtig, sich dessen bewusst zu sein, andernfalls könnte es unbemerkt schleichen und seltsame Fehler verursachen.
Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow