Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

Scala Grundkurs

Closures

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Closures ermöglichen es, Funktionen wie Objekte zu behandeln und diese an beliebigen Stellen kompakt zu definieren. Welche Einsatzmöglichkeiten es dafür gibt und welche Besonderheiten Sie bei der Verwendung von Closures beachten sollten, zeigt Ihnen dieses Video.

Transkript

Scala ist eine funktionale Programmiersprache. Als solche muss Scala also Funktionen anders behandeln als beispielsweise Programmiersprachen, wie Java es tun. Das äußert sich beispielsweise dadurch, dass Funktionen nicht nur auf Klassenebene definiert werden, sondern effektiv sind solche Funktionen Objekte, die innerhalb des Programmcodes definiert werden können. Diese bezeichnet man unter Umständen auch als Closure oder Lambda, und ich zeige Ihnen jetzt, was genau es damit auf sich hat. Ich befinde mich nun also in meinem Programmcode. Hier gibt es nun beispielsweise Kunden, in dem Fall also den ersten Kunden, Christopher Janietz und den zweiten Kunden, Maria Maier. Als nächstes könnte ich also nun eine Closure defineren. Eine Closure ist also ein Funktionsobjekt. Das bedeutet, ich erzeuge dieses Funktionsobjekt z. B. durch Zuweisung in eine Konstante. Bei der Deklaration gebe ich zunächst einmal nun, ähnlich wie bei einer normalen Funktion, die Parameter an, in meinem Fall also nun der Parameter "Customer", denn ich möchte einen Customer in irgendeiner Art und Weise verarbeiten. Als nächstes signalisiere ich durch diesen Pfeil, dass ich eine Impementierung bereitstellen möchte für diese Funktion. Die Implementierung ist nun beispielsweise das Erzeugen eines Strings. In meinem Fall nun konkret, dass ich von dem Customer-Objekt innerhalb dieser Closure den "firstname" nehme, als auch den "lastname", und das zum gesamten Namen so kombiniere. Da es sich also um eine solche Funktion handelt, kann ich diese auch einfach aufrufen. Beispielsweise durch "closure(customer)". Das Ganze gebe ich noch auf die Konsole aus, und starte die Anwendung. Ich bekomme also hier die Information "Christopher Janietz", da ich den Customer Christopher Janietz in diese Funktion geschickt habe. Jetzt könnte ich allerdings auch eine Funktionskonstante erstellen, die ihren Zweck viel besser darstellt. Beispielsweise eine Closure mit der Bezeichnung "isYoung". Um zu überprüfen, ob die Person, die ich innerhalb der Funktion auswerte, jung ist. Um den Typen schon rechzeitig zu signalisieren, verwende ich lediglich die Typen innerhalb dieser Funktionsdefinition. Also ganz konkret heißt es in dem Fall, ich möchte einen Customer entgegennehmen, also nehme ich den Typ "Customer", und aus einem "Customer" generiere ich einen "Boolean". Durch die Überprüfung, ob die Person also jung ist. Damit überlasse ich anders hier nicht mehr dem Compiler die Möglichkeit, den Typen selbst zu erzeugen beziehungsweise zu definieren, sondern ich lege ihn explizit fest. Das bedeutet auch, dass die Signatur meiner nun zu definierenden Funktion auch genau diesem Typen hier entsprechen muss. Also wiederum nehme ich einen "Customer" entgegen, und auf dem Customer nutze ich das Feld "age" und überprüfe, ob dies kleiner ist als dreißig, genau dann kommt ein Wert von "true" oder "false" raus. Eine solche Closure-Funktion kann ich nun beispielsweise auch an andere Funktionen übergeben, ein Beispiel dafür ist die Funktion "exists" auf einem "Option". Ich kann also ein "Option" erzeugen, beispielsweise also vom "customer" "Christopher Janietz", und benutze dann den Aufruf der Funktion "exists". Dieser nimmt, ähnlich wie hier definiert, einen Closure entgegen, das aus einem Customer einen Boolean mappt. Das bedeutet, meine Funktion "isYoung" ist perfekt dafür geeignet, hier übergeben zu werden. In dem Fall ist die Person also nun als jung eingestuft worden, mit einem Alter kleiner als 30. Das Ganze kann ich auch mit Hilfe von Listen tun. Beispielsweise könnte ich mir eine Liste aller jungen Kunden erzeugen lassen. Dafür nehme ich zunächst einmal alle Kunden, also den Herren Christopher Janietz und die Frau Maria Maier, und als nächstes filtere ich nun. Dieser Filter nimmt ähnlich wie die "exists"-Funktion also ein Closure entgegen, das aus einem Customer einen Boolean-Wert generiert. Also wiederum perfekt geeignet für meine Funktion "isYoung". Das Ganze gebe ich noch auf die Konsole aus, und in dieser Liste befindet sich nun nur Christopher Janietz. Allerdings muss ich nicht wie hier gezeigt eine solche Funktionsdefinition innerhalb einer Konstante vornehmen. Ich kann das Ganze auch Inline tun. Beispielsweise erzeuge ich wiederum eine Liste der Kunden, "customer" und "customer2", ich verwende wiederum den Filter, und anders als zuvor definiere ich nun mit geschweiften Klammern einen Funktion innerhalb dieses Blocks. Ich vergebe also hier einen Namen für die Variable, zum Beispiel "customer". Dieser kommt also nun durch die Liste von Customern in diese Funktion hinein. Als nächstes überprüfe ich für jeden dieser Customer, ob dessen Alter nun beispielsweise kleiner als 25 ist. In dem Fall erhalte ich nun also eine leere Liste, da Christopher Janietz z. B. genau 25 Jahre alt ist. Allerdings kann ich diese Syntax noch um einiges verkürzen. Ich beginne also wieder mit einer Liste der Kunden und wiederum mit der Funktion "filter". Als nächstes nutze ich nun keine geschweiften Klammern mehr, bedingt dadurch, dass es hier nur ein einziges Argument gibt, den Kunden, kann ich hier auch eine besondere Notation nutzen. Mit Hilfe von "_" sage ich, bitte verwende das erste Argument und von genau diesem ersten Argument nehme ich also nun beispielsweise das Alter und überprüfe, ob es größer als 25 ist. Diese Notation ist also schon deutlich kompakter. Alternativ kann ich auch noch in meiner Liste von Kunden einen Filter ausführen, der sich in dem Fall nicht mehr durch normale Klammersetzung definiert, sondern ausschließlich durch ein Leerzeichen und geschweifte Klammern, danach schließe ich die Klammer des Printlines und nun kann ich beispielsweise den Kunden als Argument "c" entgegen nehmen, und dann überprüfen, ob er beispielsweise älter als 25 ist. Das sind also die verschiedenen Möglichkeiten, wie ich Inline eine solche Closure beziehungweise Lambda erzeugen kann. Allerdings kann ich auch mit Referenzen arbeiten. Ich definiere hier beispielsweise ein "object", nenne es in dem Fall "Reference", und darauf definiere ich nun eine Funktion "isMale", diese überprüft auf Basis eines Kunden mit einem Ausgabewert "Boolean", ob dessen Geschlecht männlich ist. Hier möchte ich nun also mit einer Referenz auf diese Funktion innerhalb beispielsweise einer anderen Klasse oder wie in diesem Fall ein "object" verweisen. Ich nehme also wiederum die Liste der Kunden und filtere diese nun anhand einer Funktion "Reference.isMale". Wichtig ist, dass ich hier keine Klammern setze. Würde ich hier Klammern setzen, so würde ich versuchen, quasi diese Funktion auszuwerten, stattdessen übergebe ich sie als Referenz an die Filterfunktion. Oftmals findet man solche Closures beziehungsweise Lambdas auch im Kontext als Callback-Funktion. Innerhalb meiner Anwendung nutze ich aktuell APIs, dieser rufe ich auf und gebe dann entsprechend eine Weitermeldung, ob der Aufruf erfolgreich war. Aktuell passiert das alles blockierend, das bedeutet, sobald der Inhalt runtergeladen werden soll, muss die Anwendung warten. Allerdings könnte ich beispielsweise das Herunterladen der Daten in einen Thread auslagern. Ich erzeuge also einen "Thread", hier benötige ich nun lediglich eine Inline-Funktion, die dann das Herunterladen übernimmt. Ich starte also hier den "Thread", und automatisch wird nun meine Funktion "postToUrl" nicht mehr darauf warten, dass der Inhalt von der Internetseite heruntergeladen wurde. Was wäre aber, wenn sich beispielsweise die Methoden "charge1" und "charge2" für den Inhalt interessieren würden? Dafür kann ich nun beispielsweise einen Callback verwenden. Dieser funktioniert ähnlich wie man es bereits von Closures kennt. Ich definiere also hier ein Argument "callback" und gebe ihm eine Signatur. In dem Fall sende ich also einen String, das ist der Inhalt der Website und erwarte keine Rückgabe. Also "Unit". Als nächstes kann nun innerhalb von der "postToUrl"-Funktion ein solches Closure definiert werden. Beispielsweise nimmt es "content" entgegen und gibt diesen auf die Konsole aus. Selbstverständlich muss ich nun noch einen Aufruf des Callbacks machen. Das tue ich hier mit dem Inhalt, der heruntergeladen wurde. Und man sieht auf der Konsole nun die Ausgabe von dem Inhalt der Website "200 OK". In dem Fall also dieser URL. An der Stelle sei angemerkt, dass Scala für Mechanismen wie Parallelisierung eigene Konstrukte bietet, und nicht ähnlich wie in JavaScript sich auf Callbacks verlassen muss. Das hier war lediglich ein Beispiel, das der Demonstration diente. Closures und Lambdas bezeichnet man also als Inline-Funktion. Oder Funktionen, die man beispielsweise Konstanten oder auch Variablen zuweisen kann. Diese sind verfügbar als Eingabeparameter oder auch als Ausgabetyp. So kann beispielsweise eine Funktion auch eine Closure erzeugen. Die Typendeklaration findet dadurch statt, dass man beispielsweise angibt, dass eine solche Closure aus einem "int" einen String erstellt. Oder einen String entgegennimmt und keinen Rückgabewert liefert, also beispielsweise Unit. Sollte es nur einen Parameter geben, so ist die Parameterbindung über einen Underscore möglich. So kann man beispielsweise die Notation deutlich verkürzen. Auch das Setzen von Klammern ist unter Umständen nicht immer notwendig, je nach dem welche Art von Stil man für den Aufruf pflegen möchte. Am Ende zählt natürlich immer, dass die Lesbarkeit das Wichtigste am Code ist.

Scala Grundkurs

Entdecken Sie die Möglichkeiten und Eigenschaften der modernen Programmiersprache Scala.

4 Std. 44 min (39 Videos)
Derzeit sind keine Feedbacks vorhanden...
 
Exklusiv für Abo-Kunden
Erscheinungsdatum:12.04.2017

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!