Swift Funktionsaufruf - Übergabe soll einen Funktionsaufruf (Pointer) enthalten

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Swift Funktionsaufruf - Übergabe soll einen Funktionsaufruf (Pointer) enthalten

    Hallo,

    ich möchte in Swift eine Funktion aufrufen und dieser den Pointer auf eine eigene Funktion übergeben, die dann ausgeführt bzw. aufgerufen wird, sofern Parameter_2 übergeben wurde. Der zweite Parameter soll optional sein.

    Beispiel:
    funktionsname(parameter_1: Int, parameter_2: funktionBerechne()) -> Int
    {
    var ergebnis = 0

    // Verarbeite parameter_1

    if (parameter_2 vorhanden)
    {
    // Rufe Funktion auf
    }

    return ergebnis
    }

    Ich komme hier einfach nicht weiter. ?( Eine Fehlermeldung erhalte ich nicht. :huh:

    Kann mir jemand vielleicht erklären wie so etwas umzusetzen ist bzw. vielleicht ein Beispiel mitteilen? Danke mal vorab.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von OSXDev ()

  • Mac & i Test Abo
  • Hallo!

    Deine Vorlage wäre besser zu lesen, wenn sie in einem Code-Block stünde.
    Ihr fehlen wesentlich Aspekte für ein funktionierendes Swift-Programm:
    - Syntax: Funktionen werden mit func eingeleitet. "if (parameter2 vorhanden)" ist so in
    der Regel syntaktisch nicht richtig.
    - Fehlende Elemente: funktionBerechne() und beispielhafte Aufrufe für funktionsname.
    So wie angegeben müsstest du also mehrere Fehlermeldungen bekommen.

    Ich vermute, du meinst etwa folgendes (ich habe zum Test mal einen Playground mit
    folgendem Inhalt erstellt):

    C-Quellcode

    1. //: Playground - noun: a place where people can play
    2. import Cocoa
    3. func X(parameter1 : Int, parameter2 : ((Int)->Int)? = nil) -> Int
    4. {
    5. var ergebnis = 0
    6. ergebnis = parameter1
    7. if parameter2 != nil
    8. {
    9. ergebnis = parameter2!(ergebnis)
    10. }
    11. return ergebnis;
    12. }
    13. func Verdoppeln(parameter : Int) -> Int
    14. {
    15. return 2 * parameter
    16. }
    17. X(parameter1: 30)
    18. X(parameter1: 20, parameter2: Verdoppeln)
    Alles anzeigen
    X liefert beim ersten Aufruf 30 und beim zweiten 40.

    Grüße
    Marco
  • marcoo schrieb:

    Deine Vorlage wäre besser zu lesen, wenn sie in einem Code-Block stünde.
    ...

    Ich vermute, du meinst etwa folgendes (ich habe zum Test mal einen Playground mit
    folgendem Inhalt erstellt):
    Hallo Marco,

    ja stimmt, ist besser lesbar in einem Code-Block. Naja, sollte auch nur eine Pseudofunktionsbeschreibung darstellen. War wohl zu müde. :)

    Mit Deiner Vermutung liegst Du richtig. :thumbsup: Habe meinen Fehler gefunden. :D

    Vielen Dank
  • marcoo schrieb:

    C-Quellcode

    1. func X(parameter1 : Int, parameter2 : ((Int)->Int)? = nil) -> Int
    2. {
    3. var ergebnis = 0
    4. ergebnis = parameter1
    5. if parameter2 != nil
    6. {
    7. ergebnis = parameter2!(ergebnis)
    8. }
    9. return ergebnis;
    10. }

    Warum hier so umständlich und dann auch noch mit einem bösen explicitly unwrapped optional?

    Quellcode

    1. func X(parameter1: Int, parameter2: ((Int)->Int)? = nil) -> Int
    2. {
    3. return parameter2?(parameter1) ?? parameter1
    4. }

    ;)

    PS: In Swift Funktionsnamen bitte mit Kleinbuchstaben beginnen.^^
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • MCDan schrieb:

    Ganz ehrlich, ich würde Lösung 1 nehmen. Da kann man auf einem Blick erkennen, was die Methode macht.

    Mit entsprechender Swift-Erfahrung, gegen die Du Dich ja harnäckig wehrst, ist L2 genauso lesbar.

    MCDan schrieb:


    Sollte Lösung 2 bei der Laufzeit wirklich deutlich schneller sein, was ich mir nicht vorstellen kann, dann sollte man lieber den Compiler optimieren. ;)

    Um Geschwindigkeit geht es dabei nicht. Ich wäre enttäuscht, wenn der Compiler nicht bei beidem das gleiche liefert. Das überprüfe ich jetzt aber nicht.

    Abgesehen davon, daß ich diese Kurzform auch ein bißchen aus Spaß an der Sache anbringen wolte, ginge es mir eher darum, auf den EUO hizuweisen. Bei vergleichbaren, aber komplexeren Geschichten kann der auch gerne mal an der falschen Stelle eingebaut werden, und andersrum kann man so ein Spargel-Ausrufezeichen beim lesen gerne übersehen…

    Das 'unexpectedly found nil while unwrapping…' in Swift ist anscheinend das neue 'selector not recognized'… o_O
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • torquato schrieb:

    Um Geschwindigkeit geht es dabei nicht. Ich wäre enttäuscht, wenn der Compiler nicht bei beidem das gleiche liefert. Das überprüfe ich jetzt aber nicht.

    Ich konnte das Mausern einfach nicht sein lassen. :)

    xcrun swiftc -Osize -emit-assembly test.swift liefert erwatungsgemäß ein identisches Ergebnis. Yeeaaahh! \o/

    Quellcode

    1. $ xcrun swiftc --version
    2. Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1)
    3. Target: x86_64-apple-darwin17.4.0
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • torquato schrieb:

    MCDan schrieb:

    Ganz ehrlich, ich würde Lösung 1 nehmen. Da kann man auf einem Blick erkennen, was die Methode macht.
    Mit entsprechender Swift-Erfahrung, gegen die Du Dich ja harnäckig wehrst, ist L2 genauso lesbar.

    Uns jeder der das lernt ohne eine Beamtenanstellung als Swift-Programmierer zu haben, ist entweder Hobbyist oder hat Zuviel Langeweile

    Wer vom programmieren leben will/muss wird einen teufel tun und seine zeit verschwenden um eine Insellösung zu erlernen bei der er alles bisher erlernte vergessen muss und bei 0 anfangen muss und die in 5 Jahren eh keine Sau mehr interessiert.

    Gruss

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Wer vom programmieren leben will/muss wird einen teufel tun und seine zeit verschwenden um eine Insellösung zu erlernen bei der er alles bisher erlernte vergessen muss und bei 0 anfangen muss und die in 5 Jahren eh keine Sau mehr interessiert.
    Die Objective-C Insel ist doch die Selbe. Schau dich doch mal um, worüber auf den ganzen Konferenzen gesprochen wird. Zu Objective-C findest du da nicht mehr viel. Die Leute da draußen scheinen also recht gut von/mit Swift leben zu können. Solche Aussagen klingen für mich in etwa so, wie die von alten Netzwerkadministratoren, die meinen IPv6 ist nur eine Modeerscheinung und geht auch wieder weg.
  • Thallius schrieb:


    Wer vom programmieren leben will/muss wird einen teufel tun und seine zeit verschwenden um eine Insellösung zu erlernen bei der er alles bisher erlernte vergessen muss und bei 0 anfangen muss und die in 5 Jahren eh keine Sau mehr interessiert.

    1.) Insellösung? Echt jetzt? Also, Objective-C ist platformübergreifend überall super einsatsfähig? Wirklich? o_O

    2.) Wer vom Programmieren leben will, MUSS (!) neue Sprachen, Konzepte, Frameworks, libs, etc. _immer_ im Auge behalten und sollte sich damit auch je nach Schwerpunkt weiter beschäftigen. Wenn Du (stellvertretend) _richtig_ programmieren kanst, dann ist Swift, oder Rust als C-Parallele, nur ein relativ kleiner Hosenschiß.
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Michael schrieb:

    Thallius schrieb:

    Wer vom programmieren leben will/muss wird einen teufel tun und seine zeit verschwenden um eine Insellösung zu erlernen bei der er alles bisher erlernte vergessen muss und bei 0 anfangen muss und die in 5 Jahren eh keine Sau mehr interessiert.
    Die Objective-C Insel ist doch die Selbe. Schau dich doch mal um, worüber auf den ganzen Konferenzen gesprochen wird. Zu Objective-C findest du da nicht mehr viel. Die Leute da draußen scheinen also recht gut von/mit Swift leben zu können. Solche Aussagen klingen für mich in etwa so, wie die von alten Netzwerkadministratoren, die meinen IPv6 ist nur eine Modeerscheinung und geht auch wieder weg.
    Ganz schlechter Vergleich. iP6 ist eine notwendige Erweiterung weil das alte System nicht mehr ausreicht. Swift ist einfach nur mal was neues das aber keinen Mehrwert bringt, denn bessere Software kann ich damit auch nicht programmieren. In Endeffekt bestimmt immer noch das können des Entwicklers die Qualität der Software und nicht die verwendete Sprache....

    Allerdings versucht man heutzutage immer mehr das Nichtskönnen der meisten Programmierer durch möglichst intelligente IDE und dependenci Manager zu kompensieren. In meinen Augen aber der falsche Weg...
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Ganz schlechter Vergleich. iP6 ist eine notwendige Erweiterung weil das alte System nicht mehr ausreicht. Swift ist einfach nur mal was neues das aber keinen Mehrwert bringt, denn bessere Software kann ich damit auch nicht programmieren.
    Der Vergleich zielte vor allem darauf ab, dass du meinst Swift gehe wieder weg. Wer die Augen vor der Realität nicht verschließt wird wohl oder über feststellen müssen, dass sich in 5 Jahren eher keine Sau mehr für Objective-C interessiert. Moment, sagte ich 5 Jahre? Ach nee, jeder Neueinsteiger auf den Apple Plattformen interessiert sich schon heute nicht mehr für Objective-C. Das kann man gut finden oder nicht. Aber meiner Meinung nach werden wir Swift nicht mehr los. Oder vielleicht doch, wenn Apple weiter so viel „Qualitätssoftware“ bringt. Nur dann ist Objective-C auch tot.

    Seit der Vorstellung von Swift, wird Swift von den „alten Objective-Clern“ eine Totgeburt prophezeit, nur die Welt da draußen bekommt davon komischerweise nix mit und dreht sich einfach weiter.

    Thallius schrieb:

    Allerdings versucht man heutzutage immer mehr das Nichtskönnen der meisten Programmierer durch möglichst intelligente IDE und dependenci Manager zu kompensieren. In meinen Augen aber der falsche Weg..
    Keine Angst. Apple und intelligente IDEs schließt sich gegenseitig aus. Sonst wäre Xcode nicht in diesem Zustand, wie es jetzt ist.
  • torquato schrieb:

    marcoo schrieb:

    C-Quellcode

    1. func X(parameter1 : Int, parameter2 : ((Int)->Int)? = nil) -> Int
    2. {
    3. var ergebnis = 0
    4. ergebnis = parameter1
    5. if parameter2 != nil
    6. {
    7. ergebnis = parameter2!(ergebnis)
    8. }
    9. return ergebnis;
    10. }
    Warum hier so umständlich und dann auch noch mit einem bösen explicitly unwrapped optional?

    Quellcode

    1. func X(parameter1: Int, parameter2: ((Int)->Int)? = nil) -> Int
    2. {
    3. return parameter2?(parameter1) ?? parameter1
    4. }
    ;-)

    PS: In Swift Funktionsnamen bitte mit Kleinbuchstaben beginnen.^^
    Danke für die Tipps. Ich hatte mich an die Vorlage gehalten und nicht geprüft, was ich noch verbessern würde.
    Deshalb auch das X.
    Dass ein so kompakter Einzeiler reicht geht, war mir aber tatsächlich neu.

    Grüße
    Marco
  • Michael schrieb:

    Thallius schrieb:

    Ganz schlechter Vergleich. iP6 ist eine notwendige Erweiterung weil das alte System nicht mehr ausreicht. Swift ist einfach nur mal was neues das aber keinen Mehrwert bringt, denn bessere Software kann ich damit auch nicht programmieren.
    Der Vergleich zielte vor allem darauf ab, dass du meinst Swift gehe wieder weg. Wer die Augen vor der Realität nicht verschließt wird wohl oder über feststellen müssen, dass sich in 5 Jahren eher keine Sau mehr für Objective-C interessiert. Moment, sagte ich 5 Jahre? Ach nee, jeder Neueinsteiger auf den Apple Plattformen interessiert sich schon heute nicht mehr für Objective-C. Das kann man gut finden oder nicht. Aber meiner Meinung nach werden wir Swift nicht mehr los. Oder vielleicht doch, wenn Apple weiter so viel „Qualitätssoftware“ bringt. Nur dann ist Objective-C auch tot.
    Seit der Vorstellung von Swift, wird Swift von den „alten Objective-Clern“ eine Totgeburt prophezeit, nur die Welt da draußen bekommt davon komischerweise nix mit und dreht sich einfach weiter.

    Diese Aussage bezogt sich auch mehr darauf, dass meiner Meinung nach in 5 Jahren kein Mensch mehr native Apps programmmieren wird. Der Trend geht ganz klar zu plattform übergreifenden Lösungen wo man möglichst wenig code schreiben muss. Klar betrifft das nicht die Hobbiisten aber für die rede ich hier auch nicht. Und es wird auch immer ein paar Nischenlösungen bleiben die weiterhin native gemacht werden. Aber der MArkt wird dermassen klein werden, dass ich für meinen Teil da nicht drauf spekulieren würde meinen Lebensunterhalt damit verdienen zu können. Zumindest nicht als Anfänger oder Neuling. Wenn man alt eingesessen ist und ein erfolgreiches Produkt weiter pflegt bzw. entwickelt mag das anders aussehen aber da ist der größte Teil ja eh immer noch Objective-C

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Quellcode

    1. //: Playground - noun: a place where people can play
    2. import Cocoa
    3. func rechne(parameter1: Int, parameter2: ((Int)->Int)? = nil) -> Int
    4. {
    5. return parameter2?(parameter1) ?? parameter1
    6. }
    7. func rechneNochmal(parameter3: Int) -> Int
    8. {
    9. return 2 * parameter3
    10. }
    11. rechne(parameter1: 30)
    12. rechne(parameter1: 20, parameter2: rechneNochmal)
    13. rechneNochmal(parameter3: 40)
    14. // Der nachfolgende Aufruf wird mit folgender Fehlermeldung quitiert: "Cannot convert value of type 'Int' to expected argument type '((Int) -> Int)?'"
    15. rechne(parameter1: 30, parameter2: rechneNochmal(parameter3: 20))
    Alles anzeigen
    Benötige nochmals etwas Unterstützung. Eine Erläuterung wäre auch nicht schlecht.

    Wenn ich die Funktion rechne() wie in Zeile 21 aufrufe, dann erhalte ich eine Fehlermeldung s. Zeile 20. Was diese besagt, dachte ich zumindest, ist mir klar, nur wie bzw. was muss ich abändern, dass ich parameter2 eine Funktion mit Parametern übergeben kann?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von OSXDev ()

  • Ich bin dabei mein Swift Programm hinsichtlich der Länge des Quellendes zu optimieren bzw. diesen zu reduzieren.

    Es wäre super wenn ich der Funktion rechne() einen Funktionsaufruf mit Parameter übergeben könnte. Um dies zu erreichen habe ich eine Alternative unter Zuhilfenahme eines dritten Parameters realisiert. Dieses Konstrukt funktioniert auch, nur leidet die Lesbarkeit enorm darunter. Im übrigen bin ich mir sicher, dass ich dieses Konstrukt nach einer Zeitspanne bestimmt nicht gleich auf Anhieb wieder verstehe ohne den Code zuvor durchzusehen. Natürlich könnte ich dies in einem riesigem Kommentar niederschrieben, aber naja "schön" ist anders. ;)

    Konzeptionell gibt es bestimmt noch weitere Lösungsansätze, nur will ich jetzt nicht alles neu strukturieren. Das würde dazu führen, dass ich einen Großteil neu schreiben müsste. Diesen Aufwand möchte ich mir ersparen. 8)

    Funktioniert der von mir favorisierte Lösungsansatz evtl. gar nicht und muss ich es doch bei einem dritten Parameter belassen? ?(

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von OSXDev ()

  • OSXDev schrieb:

    Quellcode

    1. // Der nachfolgende Aufruf wird mit folgender Fehlermeldung quitiert: "Cannot convert value of type 'Int' to expected argument type '((Int) -> Int)?'"
    2. rechne(parameter1: 30, parameter2: rechneNochmal(parameter3: 20))

    In dem Fall kannst Du natürlich auch Funktionen definieren, die ihrerseits wieder Funktionen, bzw. Closures zurückgeben. z.B.:

    Quellcode

    1. func multiply(by: Int) -> (Int) -> Int {
    2. return { x in x * by }
    3. }
    4. func add(_ y: Int) -> (Int) -> Int {
    5. return { x in x + y }
    6. }
    7. func calculate(_ x: Int, _ predicate: (Int) -> Int) -> Int {
    8. return predicate(x)
    9. }
    10. var result = calculate(20, multiply(by: 3)) // 60
    11. var resultB = calculate(20, add(5)) // 25
    Alles anzeigen

    Aber sowas will gut desinged und durchdacht sein, und da Du Dich da anscheinend auf dem Feld noch schwer tust, würde (freundlichst) eher davon abraten.
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Also, mir ist nicht klar, welches Konstrukt du ersetzen/verkürzen willst.

    OSXDev schrieb:

    Quellcode

    1. import Cocoa
    2. func rechne(parameter1: Int, parameter2: ((Int)->Int)? = nil) -> Int
    3. {
    4. return parameter2?(parameter1) ?? parameter1
    5. }
    Diese Funktion ist doch sinnlos. Wenn du keine Funktion als zweiten Parameter übergibst, braucht man die Funktion gar nicht erst aufrufen, sondern arbeitet direkt mit parameter1 weiter. Übergibst du eine Funktion, kannst du die auch gleich direkt aufrufen.

    OSXDev schrieb:

    Quellcode

    1. // Der nachfolgende Aufruf wird mit folgender Fehlermeldung quitiert: "Cannot convert value of type 'Int' to expected argument type '((Int) -> Int)?'"
    2. rechne(parameter1: 30, parameter2: rechneNochmal(parameter3: 20))
    Hier übergibst du als parameter2 ja keine Funktion, sondern das Ergebnis eines Funktonsaufrufs.
  • @torquato: Danke für das Beispiel. :thumbsup: Was Deinen freundlichen Rat angeht, naja hätte nicht jemand über den Tellerrand geschaut wäre die Erde heute noch eine Scheibe. Oder man wächst an seinen Herausforderungen. :) Wie auch immer, Dein Beispiel hat mir geholfen einen Einstieg in diese Materie zu finden und ich nehme dies gern zum Anlass diese zu vertiefen.

    Vielen Dank

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von OSXDev ()