Ich habe eine sehr einfache Frage. Dies gilt nicht nur für Spray-Json, ich habe ähnliche Behauptungen mit Argonaut und Circe gelesen. Also bitte erleuchte mich.
In spray-json bin ich auf die Aussage mit There is no reflection involved
gestoßen. Ich verstehe für Typ Klassen basierte Ansatz, wenn der Benutzer bietet JsonFormat dann ist alles in Ordnung. Aber gilt diese Behauptung auch für die Verwendung von DefaultJsonProtocol
?
Denn wenn wir uns dies , können Sie die Verwendung von clazz.getMethods
, clazz.getDeclaredFields
etc. sehen. Isn ' t dies die Verwendung von Reflexion? Obwohl natürlich, dank object#apply
, müssen wir uns keine Gedanken darüber machen, anders als in der Java-Welt mit Reflektion zu setzen. Aber wenigstens zum Lesen der Feldnamen verstehe ich nicht, wie man die Reflexion übersehen kann.
Ich bin mit spray-json nicht sehr vertraut, deshalb werde ich seine Behauptungen über Reflektion nicht verteidigen, die definitiv mit den Teilen von ProductFormats
, auf die Sie hinweisen, im Widerspruch stehen.
Ich weiß mehr über circe und Argonaut und argonaut-formlos und Play JSON, die alle eine Art von Reflektion verwenden, um Codecs für Fallklassen und andere benutzerdefinierte Typen abzuleiten. Der wichtigste Punkt ist, dass diese Bibliotheken keine Laufzeit Reflexion verwenden - sie bestimmen die Feldnamen und andere Informationen, die sie zur Kompilierungszeit benötigen, über das Scala-Makrosystem.
Wenn man im Kontext von Java oder Scala von "Reflektion" spricht, meint man allgemein Laufzeitreflexion, aber Makros unterstützen auch eine Art Reflexion. Wenn ich persönlich darüber spreche, wie Ableitung in diesen Bibliotheken funktioniert, versuche ich es zu sein vorsichtig angeben, dass keine Laufzeit Reflexion beteiligt ist.
Sie können argumentieren, dass die Reflektion zur Kompilierungszeit (oder Metaprogrammierung oder wie immer Sie sie nennen wollen) viel weniger schlecht ist als die Laufzeitreflexion. Es kann Ihren Code komplexer machen und es ist sehr leicht zu missbrauchen, aber es bringt nicht die gleiche Fragilität wie die Laufzeit-Reflektion mit sich und untergräbt nicht Ihre Fähigkeit, Ihren Code auf die gleiche Weise wie die Laufzeit-Reflektion zu verstehen tut. Wenn Sie verstehen, was das Makro macht (was ein großes if ist), werden Sie nie von der Laufzeit überrascht sein.
Bei den Typen geht es im Grunde darum, Programme mit schlechtem Potenzial zurückzuweisen, bevor Sie sie ausführen, und die Selbstprüfung von Typen während der Laufzeit verwirrte dies alles (als Erik Osheim sagt , "Wenn du einen Type in Runtime triffst, töte ihn"). Auf der anderen Seite ist die Introspektion von Typen zur Kompilierzeit genau das, was Compiler tun, und Makros geben Ihnen als Programmierer einfach eine saubere Möglichkeit, sich an diesem Prozess zu beteiligen (oder zumindest relativ sauber im Vergleich zum Schreiben von Compiler-Plugins usw.). ).
Es kann auch Leistungsvorteile geben, Laufzeitreflexionen zu vermeiden, aber für mich persönlich ist das eher zweitrangig - ich hasse Laufzeitreflexionen, weil ich zu viel von meinem Leben verschwendet habe, um schrecklichen Java-Code zu entschlüsseln, der schreckliche Java-Bibliotheken verwendet bei der Laufzeit-Reflektion - nicht weil die Laufzeit-Reflektion meine Programme marginal langsamer machen könnte.
Das ist alles eine sehr langatmige Art zu sagen, dass Sie in diesem Zusammenhang lesen sollten, "es gibt keine Reflexion", da "es keine Laufzeitreflexion gibt" (und selbst dann sollten Sie den Autor nicht beim Wort nehmen , Schätze ich, angesichts all der getMethods
Zeug in Spray-JSON).
Tags und Links scala spray-json