Optionals, Optionals - wieso eigentlich

  • gritsch schrieb:


    doch, obj-c hat optionals bei objektpointern denn du kannst ihnen nil zuweisen (das ist bei obj-c im prinzip der "kein wert" indikator der optionals bei swift).nur in C gibts keine optionals.

    und warum soll man die rufezeichen in swift vermeiden, in obj-c aber keine if-abfragen machen?
    du musst eben in beiden sprachen bestimmte sachen machen oder eben nicht machen dass es funktioniert.
    ob man dann lieber ein fragezeichen und sonstige konstrukte verwendet oder eine gebräuchliches für jeden lesbares if-statement ist doch komplett egal!

    Verstehe nicht, wieso eine nil-Pointerreferenz in Obj-C etwas anderes sein soll als eine null-Pointerreferenz in C.

    Ich habe nie gesagt, Du sollst keine if-Abfragen machen. Ganz im Gegenteil. Das Abprüfen ist wichtig, und genau deshalb sollte man diese Ausrufezeichen in Swift vermeiden.

    Dem letzten Satz stimme ich unumwunden zu.^^
  • macmoonshine schrieb:

    Und ein if let finde ich auch nicht ausdrucksstärker als einen expliziten Vergleich auf nil.

    Ich weiß nicht so ganz was Du mit 'Ausdrucksstärke' meinst, aber ich finde insgesamt so einen Obj-C-Code*

    C-Quellcode

    1. NSString *a
    2. NSDate *b
    3. if (foo == 5) &&
    4. ([bar isEqualTo: @"1000"]) &&
    5. ((a = [object giveMeSomething]) != nil ) &&
    6. ((b = [a giveMeSomethingElse]) != nil ) {
    7. // do the work here
    8. [a doSomething]
    9. [b doSomethingElse: a]
    10. }
    11. else {
    12. // exit context
    13. }
    Alles anzeigen

    insgesamt ja nicht so toll, wenn man ihn mit einer Swift-Version vergleicht.

    C-Quellcode

    1. guard
    2. foo == 5 &&
    3. bar == "1000",
    4. let a = object.giveMeSomething(),
    5. let b = a.giveMeSomethingElse()
    6. else {
    7. // exit context
    8. }
    9. // do the work here
    10. a.doSomething()
    11. b.doSomethingElse(a)
    Alles anzeigen
    Das finde ich viel schlanker, auch wegen des let, aber, wie man sieht, nicht nur, und insbesondere viel lesbarer. Der Obj-C-Code hat nach meinem Geschmack viel zuviel Code-noise.

    *Ich muß zugeben, lange nicht mehr in C oder Obj-C geschrieben zu haben. Müßte da nicht auch noch eine runde Klammer um den gesamten boolschen Ausdruck in der if-Abfrage? Geht es heute auch mit weniger Lärm in Obj-C?

    Das if let-Statement hat jedenfalls m.E. schon seine Berechtigung.
  • macmoonshine schrieb:

    Markus Müller schrieb:

    doch, denn Du kannst in swift angeben, ob Du optionale Werte verarbeitest oder eben nicht. Wenn Du optionals erwartest, musst Du den nil-Fall prüfen, genau das drückt der Code ja aus. Das meinte ich mit ausdrucksvollerem Code weiter oben. In obj hast Du immer nur Typ*
    Du meinst, dass Code ausdrucksvoller ist, wenn er voll von Frage- und Ausrufezeichen ist? Gerade die Optional-Syntax ist doch genau das Gegenteil von ausdrucksvoll. Und ein if let finde ich auch nicht ausdrucksstärker als einen expliziten Vergleich auf nil.
    Nicht, wenn er voll von ? und ! ist. Aber ich finde es gut, ausdrücken zu können, dass ein Wert niemals nil sein kann und dann brauche ich weder ? noch ! und habe nebenbei einen Compiler, der das für mich garantiert, denn ich würde es garantiert irgendwo vergessen. Und genau das ist bei obj-c der Fall. Wenn ein Wert auch nil sein kann, finde ich es gut, dass ich es am ? direkt sehe.

    Übrigens nutze ich derzeit ausschließlich obj-c im Produktivbetrieb. Der Grund dafür ist die, vorsichtig ausgedrückt, unfertige tool-chain für Swift. Die Sprache Swift als solche finde ich gut.
  • Ich möchte mal einwerfen, dass eine Referenz mit dem Wert nil sehr wohl initialisiert ist.

    Der Vorteil liegt darin, dass du dir bei einem Nicht-Optional – und das sollte die Regel sein – dir immer sicher sein kannst, dass es gültiges Objekt vorliegt. Optionals hat keinen Vorteil gegenüber Objective-C-Referenzen, sondern Nicht-Optionals.

    Du kannst dir daher doch ein paar Abfragen einsparen, etwa ist …

    Quellcode

    1. NSMutableArray *array = …;
    2. [array addObject:object];


    … potentiell gefährlich. Eine Abfrage hilft da mutmaßlich häufig auch nicht viel, weil du mit nil an dieser Stelle einfach nichts anfangen kannst. Der Gedanke ist jetzt, dass wenn du object gleich als Nicht-Optional deklarierst, man sozusagen den gesamten Weg zurückverfolgen kann, an dem es potentiell nil wird. Das hat aber zur Voraussetzungen, dass überall und immer ein Nicht-Optional verwendet wird. Es stellt sich dann die Frage, ob sich das lohnt. (Ich meine möglicherweise sogar ja. Aber dazu müsste man wirklich umfassende Analysen machen.)

    Man könnte aber auch einfach nil besser unterstützen …
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Amin Negm-Awad ()

  • tsunamix schrieb:

    In Objetive-C ist der Pointer nicht initialisiert und zeigt ins Nirvana. In Swift wird sichergestellt, daß jede Variable vor dem Zugriff initialisiert ist.
    Falsch. In Objective-C hat die Referenz den Wert nil

    tsunamix schrieb:

    Eher ein 'Tri-Optional'.

    1.) Referenz initialisiert
    2.) Referenz ist nil
    3.) Referenz ist nicht initialisiert und verweist ins Nirvana
    Falsch. Eine Referenz, die den Wert nil hat, ist initialisiert. Damit sind 1) und 2) identisch. 3) kann praktisch nicht vorkommen.

    tsunamix schrieb:

    Vielleicht etwas unsauber formuliert. Ich meinte immer initialisiert. In Swift ist es nicht möglich mit uninitilisiertem Speicher rumzufuhrwerken. (Es sei denn man arbeitet mit Unsafe[Mutable]Pointer-Typen natürlich.)
    Falsch. In Objective-C auch nicht.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • msch schrieb:

    Daher musst du überprüfen ob das Objekt einen gültigen Zustand hat, also nicht null ist. Damit man nicht jedesmal if(obj==nil) checken muss, gibts eben den ? Operator.
    Ich muss auch nicht ständig in Objective-C checken, ob eine Referenz nil ist. Für mich ist das ganz häufig ein zulässiger Zustand.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • tsunamix schrieb:

    Verstehe nicht, wieso eine nil-Pointerreferenz in Obj-C etwas anderes sein soll als eine null-Pointerreferenz in C.
    Grundlagen der Programmierung:

    NULL darf nicht dereferenziert werden, nil darf Nachrichten empfangen.

    NULL hat also quasi die Bedeutung: Unzulässig. Man darf es nur zuweisen, um etwas anderes unzulässig zu machen.

    nil hat die Bedeutung "Kein Objekt". Man darf Nachrichten an kein Objekt schicken.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Amin Negm-Awad schrieb:


    Quellcode

    1. NSMutableArray *array = …;[array addObject:object];


    … potentiell gefährlich. Eine Abfrage hilft da mutmaßlich häufig auch nicht viel, weil du mit nil an dieser Stelle einfach nichts anfangen kannst. Der Gedanke ist jetzt, dass wenn du object gleich als Nicht-Optional deklarierst, man sozusagen den gesamten Weg zurückverfolgen kann, an dem es potentiell nil wird. Das hat aber zur Voraussetzungen, dass überall und immer ein Nicht-Optional verwendet wird. Es stellt sich dann die Frage, ob sich das lohnt. (Ich meine möglicherweise sogar ja. Aber dazu müsste man wirklich umfassende Analysen machen.)

    Man könnte aber auch einfach nil besser unterstützen …

    dafür habe ich dann die addtion "addObjectIfNotNil:".

    ist einfach manchmal praktisch im eine temporäre variable und die abfrage ob das ergebnis nil ist zu umgehen.
    mir ist auch klar dass dadurch ein methodenaufruf mehr ansteht (wenn das ein problem sein sollte, dann ist man mit NSMutableArray eh falsch bedient).
  • Amin Negm-Awad schrieb:

    msch schrieb:

    Daher musst du überprüfen ob das Objekt einen gültigen Zustand hat, also nicht null ist. Damit man nicht jedesmal if(obj==nil) checken muss, gibts eben den ? Operator.
    Ich muss auch nicht ständig in Objective-C checken, ob eine Referenz nil ist. Für mich ist das ganz häufig ein zulässiger Zustand.
    Eigentlich trifft das genau des Pudels Kern meiner ursprünglichen Frage nach dem Sinn der Optionals.

    Michael Kofler schreibt in seinem Swift 2 Praxisbuch :

    Lehrbuch Swift 2 - Michael Kofler schrieb:

    An sich ist die Idee gut - wenn Optionals die Ausnahme und nichtoptionale Variablen die Regel wären. In der Praxis ist es aber leider gerade umgekehrt: Bei der Entwicklung von iOS- oder OS-X-Programmen entsteht oft der Anschein, als würde nahezu jede Eigenschaft oder Methode Optionals liefern. Die ständig erforderlichen nil-Absicherungen bzw. unzählige if-let-Zuweisungen machen den Code langatmig und schwer lesbar,
  • Sowas in der Art habe ich ja bereits weiter oben geschrieben: Man tauscht die relativ seltenen Nil-Pointer-Fehler gegen eine angeblich höhere, weil compilergestützte, Sicherheit und einen Wust von zusätzlichem Code ein. Diese Sicherheit halte ich immer noch für eine Illusion.
    „Meine Komplikation hatte eine Komplikation.“
  • gritsch schrieb:

    Amin Negm-Awad schrieb:

    Quellcode

    1. NSMutableArray *array = …;[array addObject:object];


    … potentiell gefährlich. Eine Abfrage hilft da mutmaßlich häufig auch nicht viel, weil du mit nil an dieser Stelle einfach nichts anfangen kannst. Der Gedanke ist jetzt, dass wenn du object gleich als Nicht-Optional deklarierst, man sozusagen den gesamten Weg zurückverfolgen kann, an dem es potentiell nil wird. Das hat aber zur Voraussetzungen, dass überall und immer ein Nicht-Optional verwendet wird. Es stellt sich dann die Frage, ob sich das lohnt. (Ich meine möglicherweise sogar ja. Aber dazu müsste man wirklich umfassende Analysen machen.)

    Man könnte aber auch einfach nil besser unterstützen …
    dafür habe ich dann die addtion "addObjectIfNotNil:".

    ist einfach manchmal praktisch im eine temporäre variable und die abfrage ob das ergebnis nil ist zu umgehen.
    mir ist auch klar dass dadurch ein methodenaufruf mehr ansteht (wenn das ein problem sein sollte, dann ist man mit NSMutableArray eh falsch bedient).
    Wie gesagt, häufig nützt dir das nichts. ein -addObjectIfNotNild:führt ja nicht zwingend dazu, dass dein Programm konsistent bleibt. Manchmal hilft halt addObjectOrNull:. Aber das ist Tatfrage und es bleiben noch Fälle übrig, in denen es darauf hinausläuft, dass ein Absturz die einzige Alternative ist.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • macmoonshine schrieb:

    Sowas in der Art habe ich ja bereits weiter oben geschrieben: Man tauscht die relativ seltenen Nil-Pointer-Fehler gegen eine angeblich höhere, weil compilergestützte, Sicherheit und einen Wust von zusätzlichem Code ein. Diese Sicherheit halte ich immer noch für eine Illusion.
    Ich weiß nicht, wie selten nil-Pointer-Fehler sind. Mir scheint es die häufigste Fehlerklasse zu sein. Aber das sagt ja nichts über die absolute Fehlerhäufigkeit aus.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Amin Negm-Awad schrieb:

    gritsch schrieb:

    Amin Negm-Awad schrieb:

    Quellcode

    1. NSMutableArray *array = …;[array addObject:object];


    … potentiell gefährlich. Eine Abfrage hilft da mutmaßlich häufig auch nicht viel, weil du mit nil an dieser Stelle einfach nichts anfangen kannst. Der Gedanke ist jetzt, dass wenn du object gleich als Nicht-Optional deklarierst, man sozusagen den gesamten Weg zurückverfolgen kann, an dem es potentiell nil wird. Das hat aber zur Voraussetzungen, dass überall und immer ein Nicht-Optional verwendet wird. Es stellt sich dann die Frage, ob sich das lohnt. (Ich meine möglicherweise sogar ja. Aber dazu müsste man wirklich umfassende Analysen machen.)

    Man könnte aber auch einfach nil besser unterstützen …
    dafür habe ich dann die addtion "addObjectIfNotNil:".
    ist einfach manchmal praktisch im eine temporäre variable und die abfrage ob das ergebnis nil ist zu umgehen.
    mir ist auch klar dass dadurch ein methodenaufruf mehr ansteht (wenn das ein problem sein sollte, dann ist man mit NSMutableArray eh falsch bedient).
    Wie gesagt, häufig nützt dir das nichts. ein -addObjectIfNotNild:führt ja nicht zwingend dazu, dass dein Programm konsistent bleibt. Manchmal hilft halt addObjectOrNull:. Aber das ist Tatfrage und es bleiben noch Fälle übrig, in denen es darauf hinausläuft, dass ein Absturz die einzige Alternative ist.
    Ich verwende das aber nicht um fehler zu vermeiden sondern einfach um kompakteren code zu haben.
  • Amin Negm-Awad schrieb:

    macmoonshine schrieb:

    Sowas in der Art habe ich ja bereits weiter oben geschrieben: Man tauscht die relativ seltenen Nil-Pointer-Fehler gegen eine angeblich höhere, weil compilergestützte, Sicherheit und einen Wust von zusätzlichem Code ein. Diese Sicherheit halte ich immer noch für eine Illusion.
    Ich weiß nicht, wie selten nil-Pointer-Fehler sind. Mir scheint es die häufigste Fehlerklasse zu sein. Aber das sagt ja nichts über die absolute Fehlerhäufigkeit aus.
    Das ist sicherlich schwer zu zählen, und hängt auch von der Größe der Klassen ab.

    Dereferenzierung von NULL-Pointern habe ich so gut wie nie. Senden von Nachrichten an Objekte die fälschlicherweise nil sind, kommen dagegen häufiger vor. Die fallen bei mir aber in der Regel schon relativ früh bei der Implementierung auf.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    Das ist sicherlich schwer zu zählen, und hängt auch von der Größe der Klassen ab.

    Dereferenzierung von NULL-Pointern habe ich so gut wie nie. Senden von Nachrichten an Objekte die fälschlicherweise nil sind, kommen dagegen häufiger vor. Die fallen bei mir aber in der Regel schon relativ früh bei der Implementierung auf.
    Also ich leide jetzt auch nicht darunter. Aber ich glaube schon, dass das das Häufigste ist.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?