Cast, kann mir das einer erklären?

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

  • Cast, kann mir das einer erklären?

    stackoverflow.com/questions/28…rray-of-cgpoints-in-swift

    Ich meine, wieso kann man ein Array [AnyObject] auf ein Array [NSValue] casten, aber nicht einen Eintrag dieses Arrays vom Typen AnyKey auf NSValue? Wo liegt da die innere Logik?
    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"?
  • Oje, das muss man mir erklären. 1. Was aus einem Array kommt (es handelt sich um Objective-C-Array) ist niemals nil. Das sollte der Compiler wissen. Aber auch, wenn er es nicht weiß, kann er doch den inferierten Typen optional machen. Wo stehe ich da auf der offenkundig ganz langen Leitung?
    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"?
  • Das ist eben der unterschied zwischen as und as?

    Quellcode

    1. ​myArray[0] as NSValue
    castet das ganze zu einem NSValue, der Compiler kann aber nicht sagen dass NSValue Objekte im Array sind und wirft einen fehler.

    Quellcode

    1. ​myArray[0] as? NSValue
    castet zu NSValue? also einem Optional.
    Das Herz besitzt Gründe, die die Vernunft nicht kennt.
  • Amin Negm-Awad schrieb:

    Oje, das muss man mir erklären. 1. Was aus einem Array kommt (es handelt sich um Objective-C-Array) ist niemals nil. Das sollte der Compiler wissen. Aber auch, wenn er es nicht weiß, kann er doch den inferierten Typen optional machen. Wo stehe ich da auf der offenkundig ganz langen Leitung?


    Ich denke auch, dass der Compiler dass könnte, aber der as Operator erzeugt nicht einfach so ein Optional ausser du castest zu einem optional

    Quellcode

    1. ​myArray[0] as NSValue?
    Das Herz besitzt Gründe, die die Vernunft nicht kennt.
  • Okay, es liegt am "könnte doch wissen". Was mich da aber erst recht stutzig macht, ist, dass das Array doch auf AnyObject nicht-optional typisiert ist. Daher kann er das doch erst recht (aus Swift heraus) wissen. Immerhin ist [AnyObject] doch gerade für Cocoa-Collections gedacht, die niemals nil aufnehmen können. Bug?
    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"?
  • Ich denke nicht dass es ein Bug ist. AnyObject kann nicht nil sein, richtig. Aber der Compiler kann nicht wissen dass das Array nur NSValue beinhaltet. Irgendwo dazwischen könnte sich ein NSString oder so versteckt haben. as garantiert aber dass der Cast funktioniert, während as? es nicht garantiert und ein Optional zurück gibt. Du würdest in dem Array also immer NSValue? erhalten, welches auch ein NSValue beinhaltet bis der pöse NSString dran ist, dann hast du nil.
    Das Herz besitzt Gründe, die die Vernunft nicht kennt.

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

  • Aber für den Fall, also dass ich NSValues erwarte und einen NSString drin habe, muss ich doch ohnehin kräftig Code schreiben oder werde einen Laufzeitfehler haben. Bei [NSValue] geht es doch gerade darum, dass ich als Programmierer das genau weiß. Deshalb caste ich doch. Das ist doch der Sinn und Zweck der ganzen Angelegenheit.

    Was macht er denn, wenn ich das heterogene Array mit [NSValue] caste? Prüft er gleich alles in dem Array und gibt mir nil zurück oder prüft er bei jedem Zugriff und gibt mir nur für das NSString nil zurück?
    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"?
  • Das fragst du am besten den Herrn Lattner, der hat das ganze schließlich verbrochen. Aber ich würde vermuten, dass es zur Laufzeit geprüft wird, da es zur Compilezeit ja nicht bekannt ist, sonst würde der Cast mit as funktionieren und as? wäre nicht nötig. Um die Verwirrung komplett zu machen, as! dürfte auch gehen.

    Mit dem Code und den Erwartungen hast du recht, das geht halt nur gegen die Philosophie von Swift, du sollst nicht erwarten ein Array mit NSValues zu haben, sondern du sollst es wissen/garantiert bekommen. Geht das nicht musst du halt Optionals nehmen was dir als Programmierer wiederum sagen soll, dass deine Annahme auch falsch sein kann.

    Auch wenn ich von Swift nicht begeistert bin, für mich schafft es mehr Probleme als es löst, kann man hier immerhin lobend erwähnen, dass Apple was dieses ganze Optional gedönse angeht wenigstens konsequent ist.
    Das Herz besitzt Gründe, die die Vernunft nicht kennt.
  • Amin Negm-Awad schrieb:

    Ich meine, wieso kann man ein Array [AnyObject] auf ein Array [NSValue] casten, aber nicht einen Eintrag dieses Arrays vom Typen AnyKey auf NSValue?

    Ich kann dir nicht erklären, warum der Typ auf Stackoverflow das Problem hat. Vielleicht benutzt der noch einen älteren Compiler. Ich habe das einfach mal ausprobiert und es geht. Siehe angehängtes Projekt.
    Dateien
    • Foo.zip

      (7,08 kB, 294 mal heruntergeladen, zuletzt: )
  • pierredrks schrieb:

    Evtl. ist der Compiler auch zu neu.

    Ja, stimmt. Das ist sogar wahrscheinlicher, denn Apple hat in der aktuellen Beta ja am 'as' herum geschraubt.

    pierredrks schrieb:

    Was in diesem Zusammenhang nicht viel anders als as? ist.

    Würde ich nicht sagen. as! entspricht einem as, d.h. castet nicht zu einem Optional. Das as ohne ! kann der Compiler zur Übersetzungszeit garantieren. Das as! sagt, zur Laufzeit kann das immer noch schief gehen und zu einem Programmabsturz führen. Das as? sagt, kann zur Laufzeit zu einem nil führen.
  • Nach meinem Verständnis castet as! zu einem Optional, einem implicit unwrapped optional, während as? zu einem Optional wandelt, das du selbst via if let o.ä. umwandeln musst. Daher das selbe beides Optionals.

    Der cast über as! lässt einen aber wie von Objektive-C gewohnt weiter arbeiten, also ohne zwingende Überprüfung auf nil oder eine falsche Klasse, und zur Laufzeit ein unrecognized selector oder anderen übliche Fehler erhalten.
    Das Herz besitzt Gründe, die die Vernunft nicht kennt.
  • pierredrks schrieb:

    Nach meinem Verständnis castet as! zu einem Optional, einem implicit unwrapped optional, während as? zu einem Optional wandelt, das du selbst via if let o.ä. umwandeln musst. Daher das selbe beides Optionals.

    Ich habe die neue Beta nicht installiert, aber ich glaube nicht, dass sich das Ganze anders verhält, als bei normalen Optionals:

    Quellcode

    1. var a: Int? = 10 // a ist ein Optional
    2. var b = a // b ist vom Typ Int?, also ein Optional
    3. var c = a? // c ist vom Typ Int?, also ein Optional
    4. var d = a! // d ist vom Typ Int, also kein Optional

    Aber wenn du die Beta da hast, kannst du ja mal nachgucken (Alt-Klick auf die Variable).
  • Cast, kann mir das einer erklären?

    Kurz im Playground getestet
    Zeile 3 wirft den Fehler: "error: '?' must be followed by a call, member lookup, or subscript"
    Zeile 4 sagt Int
    Wie gesagt ist nach meinem Verständnis das ! für einen implicit unwrapped optional, der sich wie ein nicht optional verhält aber zur Laufzeit crashen kann. Aber hier kann ich mich natürlich irren, bzw. kann das auch einfach missverständlich sein zwischen dem was die Doku sagt und was der Compiler macht.
    In diesem Fall würde ich sagen er macht aus dem "Optional" eine normale Variable.
    Es wird ja "implicit unwrapped" und wäre von daher schon richtig. Das ! soll dem Programmierer vermutlich einfach darauf hinweisen, dass es hier zu Problemen kommen kann.
    Dennoch würde ich d als implicit unwrapped Optional bezeichnen und nicht als "normale" Variable. Denn es könnte nil oder von einem anderem Typ sein.

    Edit:
    Ich denke hier mischt sich einfach die Semantik mit der technischen Umsetzung.
    Das Herz besitzt Gründe, die die Vernunft nicht kennt.

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

  • pierredrks schrieb:

    Zeile 3 wirft den Fehler: "error: '?' must be followed by a call, member lookup, or subscript"

    Oh, dann hat Apple auch da dran geschraubt.

    pierredrks schrieb:

    Zeile 4 sagt Int

    Das habe ich ja schon dahinter geschrieben. ;) Du solltest mal in dem Demoprojekt oben nachgucken, was bei dem Cast mit as! für ein Typ raus kommt.

    pierredrks schrieb:

    Wie gesagt ist nach meinem Verständnis das ! für einen implicit unwrapped optional, der sich wie ein nicht optional verhält aber zur Laufzeit crashen kann. Aber hier kann ich mich natürlich irren, bzw. kann das auch einfach missverständlich sein zwischen dem was die Doku sagt und was der Compiler macht.

    In der Dokumentation steht's schon richtig.
    var foo: Int!
    deklariert eine „implicit unwrapped“ Variable, die dann einfach mit foo „implizit geunwrapped“ wird. Ein Ausdruck wie
    var foo = bar!
    nennt man „forced unwrapping“ der Optional Variable bar.

    pierredrks schrieb:

    In diesem Fall würde ich sagen er macht aus dem "Optional" eine normale Variable.

    Genau.

    pierredrks schrieb:

    Es wird ja "implicit unwrapped" und wäre von daher schon richtig. Das ! soll dem Programmierer vermutlich einfach darauf hinweisen, dass es hier zu Problemen kommen kann.

    Nein, es wird „forced unwrapped“.

    pierredrks schrieb:

    Dennoch würde ich d als implicit unwrapped Optional bezeichnen und nicht als "normale" Variable. Denn es könnte nil oder von einem anderem Typ sein.

    Nein, es kann eben nicht nil sein. Auch einem „implicit unwrapped optional“ kann man nil zuweisen. dem 'd' oben kannst du kein nil zuweisen. Wenn du einen Optional „forced unwrappset“, welcher aber nil ist, macht's Boom -> Ende der Programmausführung.
  • macmoonshine schrieb:

    Michael schrieb:

    Oh, dann hat Apple auch da dran geschraubt.

    Das ist ja nicht weiter erstaunlich. Bis jetzt ist bei mir jeder Code immer mit einer neuen Swift-Version gebrochen, wobei die Sprachänderungen meines Erachtens häufig nicht notwendig waren. Der as!-Operator ist dafür ein gutes Beispiel.
    Das liegt daran, dass das von einem tiefen Plan geprägt ist. Der lautet: "Wir machen mal hier etwas und dort etwas und schauen, was dabei heraus kommt."

    Ist übrigens bei Swift nicht exklusiv. Das Verhalten von Declared-Properties in Class-Continuations hat sich bei Objective-C auch 3 Mal geändert. War das nicht auch Lattner?
    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"?