Es gibt ziemlich viele Blog-Posts (wie dies ) bei den Verwendungen der Standardbibliotheksfunktionen apply
/ with
/ run
/ also
/ let
verfügbar, die es ein bisschen einfacher machen zu unterscheiden, wann welche der hübschen Funktionen tatsächlich verwendet werden sollen.
Seit einigen Wochen gibt es sogar offizielle Richtlinien zu diesem Thema: Ссылка
Trotzdem denke ich, dass es sehr schwierig ist, die einzelnen Anwendungsfälle der Funktion durch die Funktionsnamen zu merken. Ich meine, für mich scheinen sie austauschbar zu sein, warum heißt let
nicht run
zum Beispiel?
Irgendwelche Vorschläge? Ich denke, die Namen sind nicht sehr ausdrucksvoll, was es schwierig macht, die Unterschiede zuerst zu sehen.
Hier ist ein inoffizieller Überblick darüber, wie die Namen entstanden zu sein scheinen.
let
ist von der funktionalen Programmierwelt inspiriert. Laut Wikipedia
Ein Ausdruck "let" verknüpft eine Funktionsdefinition mit einem eingeschränkten Bereich
In FP-Sprachen wie Haskell können Sie let
verwenden, um Werte an Variablen in einem eingeschränkten Bereich wie zB
Der entsprechende (wenn auch übermäßig komplizierte) Code in Kotlin wäre
%Vor% Die typische Verwendung von let
besteht darin, das Ergebnis einer Berechnung an einen Bereich zu binden, ohne den äußeren Bereich zu "verschmutzen".
Die Funktion with
basiert auf dem with
Sprachkonstrukt von Sprachen wie Delphi oder Visual Basic (und wahrscheinlich viele andere) wo
Das Schlüsselwort with ist eine Erleichterung, die Delphi für die Referenzierung bietet Elemente einer komplexen Variablen, z. B. ein Datensatz oder ein Objekt.
%Vor%kann umgeschrieben werden:
%Vor%
Das Äquivalent Kotlin wäre
%Vor% apply
wurde relativ spät in der Meilensteinphase zur stdlib hinzugefügt ( M13). Sie können diese Frage aus dem Jahr 2015 sehen, in der ein Benutzer genau nach einer solchen Funktion fragt und sogar die später zu verwendende Frage vorschlägt Name "anwenden".
In den Ausgaben Ссылка und Ссылка können Sie Diskussionen über die Benennung sehen. Alternativen wie build
und init
wurden vorgeschlagen, aber der von Daniil Vodopian vorgeschlagene Name apply
hat letztendlich gewonnen.
apply
ist ähnlich wie with
, da damit Objekte außerhalb des Konstruktors initialisiert werden können. Deshalb könnte apply
meiner Meinung nach auch with
heißen. Da with
jedoch zuerst zur stdlib hinzugefügt wurde, entschieden sich die Kotlin-Entwickler dafür, den bestehenden Code nicht zu brechen und fügten ihn unter einem anderen Namen hinzu.
Ironischerweise bietet die Sprache Xtend den sogenannten with-operator =>
was im Grunde dasselbe tut wie apply
.
also
wurde der stdlib später als apply
hinzugefügt, nämlich in der Version 1.1. Auch hier enthält Ссылка die Diskussion. Die Funktion ist im Grunde wie apply
, außer dass sie ein reguläres Lambda (T) -> Unit
anstelle einer Erweiterung Lambda T.() -> Unit
benötigt.
Unter den vorgeschlagenen Namen waren "applyIt", "applyLet", "on", "tap", "touch", "peek", "make". Aber "auch" hat gewonnen, da es nicht mit irgendwelchen Schlüsselwörtern oder anderen stdlib-Funktionen kollidiert und seine Verwendungen (mehr oder weniger) wie englische Sätze lesen.
Beispiel
%Vor%liest ein bisschen wie
Creater, erstelle das Objekt und auch initialisiere es!
Andere stdlib-Funktionen, deren Verwendungen ein bisschen wie englische Sätze lesen, sind takeIf
und takeUnless
, die auch in Version 1.1 hinzugefügt wurden.
Schließlich verfügt die Funktion run
über zwei Signaturen. Die erste fun <R> run(block: () -> R): R
nimmt einfach ein Lambda und läuft . Es wird hauptsächlich verwendet, um das Ergebnis eines Lambda-Ausdrucks einer Top-Level-Eigenschaft zuzuordnen
Die zweite Signatur fun <T, R> T.run(block: T.() -> R): R
ist eine Erweiterungsfunktion, die eine Erweiterung lambda als Parameter verwendet und aus Symmetriegründen auch "run" genannt wird. Es "läuft" auch ein Lambda, aber im Kontext eines Erweiterungsempfängers
Ich kenne keine historischen Gründe für die Benennung.
Hinzufügen zur Antwort von @kirillRakhman:
Ein großer Teil des Namensfindungsprozesses war (noch) fließende Leseerfahrung in wichtigen Anwendungsfällen.
with
:
apply
:
also
:
IMHO funktioniert es wirklich nicht mit let
gut. Immerhin wurde es aus "diesen beängstigenden FP-Sprachen" entnommen. Aber ich denke oft an eine Art Let's do this!
-Konstrukt. Wie unten könnte man den Code als let's print it!
lesen:
Ich empfehle dringend, diesen Blog zu lesen, um alle diese Bereichsfunktionen zu verstehen .
Einige Schlüssel dieses Blogs:
Nach dem ersten Buchstaben von jedem erhalten Sie das Akronym "LARA".
Häufige Anwendungsfälle
Mit
with()
entspricht funktional der Version der Erweiterungsfunktion von run()
. Daher ist es für den Anwendungsfall von Initialisieren und ausführen . Weitere Informationen .
Tags und Links lambda scoping kotlin higher-order-functions