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

  • Marco Feltmann schrieb:

    Weil die Swift–Objective-C–Integration nach wie vor Grütze ist, deshalb.

    Das hat doch mit Objective-C mal nichts zu tun. Es geht nur um den Cast-Operator.

    mattik schrieb:

    Naja, das kann der Compiler nicht immer aus den Typen herausbekommen - statische Codeanalyse kann eine Menge, aber nicht alles.

    Ja, das wäre eine logische Erklärung, ist es aber nicht. Wenn du nämlich den falschen Operator verwendest, haut ihn dir Xcode um die Ohren.

    EDIT: Ich meine den Unterschied zwischen as?/as! zu as. Der zwischen as? und as! macht ja, wenn ich mir gaaaanz viel Mühe gebe und besonders guter Laune bin (sehr seltener Fall), noch irgendwo Sinn.
    „Meine Komplikation hatte eine Komplikation.“

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

  • macmoonshine schrieb:

    EDIT: Ich meine den Unterschied zwischen as?/as! zu as. Der zwischen as? und as! macht ja, wenn ich mir gaaaanz viel Mühe gebe und besonders guter Laune bin (sehr seltener Fall), noch irgendwo Sinn.

    Da wurde ja auch zwischen den Versionen etwas dran herumgeschraubt - habe mir die Doku zu 1.2 nochmal durchgelesen: Das normale as geht nur für casts, die prinzipiell immer klappen. Bei welchen, bei denen der Compiler meint, dass die zur Laufzeit kaputt gehen können, verlangt die dir Sprache halt ab, dich explizit entweder für ein ! oder ein ? zu entscheiden. ! = Ich nehme es auf meine Kappe, ? = Mach's zur Laufzeit, sprich: Optional. Finde ich fair - wenig Tipperei, wenig Runtime-Overhead, trotzdem explizit genug, um später keine bösen Überraschungen zu erleben - und ganz gut lesbar (wahrscheinlich, wenn sie sich dann mal irgendwann mal auf eine Semantik festgelegt haben).

    Absurd und inkonsistent sind dann eher die Ausnahmen, z.B. dass man in switch-cases dann doch ein as statt eines as? benutzen soll und das dort sicher ist - was haben die bloß geraucht?
    Multigrad - 360°-Produktfotografie für den Mac
  • mattik schrieb:

    Das normale as geht nur für casts, die prinzipiell immer klappen.

    Ja genau: Aber wieso muss ich das als Programmierer unterscheiden? Der Compiler könnte sich ja auch automatisch darum kümmern. Nenn' mich verrückt, aber ich habe immer noch die komische Vorstellung, dass Computer und Programme das Leben einfacher machen sollen.

    mattik schrieb:

    benutzen soll und das dort sicher ist - was haben die bloß geraucht?

    Die Gefährlichkeit dieses ganzen chemischen Krams kann nicht hoch genug eingeschätzt werden.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    Ja genau: Aber wieso muss ich das als Programmierer unterscheiden? Der Compiler könnte sich ja auch automatisch darum kümmern. Nenn' mich verrückt, aber ich habe immer noch die komische Vorstellung, dass Computer und Programme das Leben einfacher machen sollen.

    Natürlich könnte der Compiler das automatisch machen - das ist reine Absicht. Der Programmierer soll diese möglichen Bruchstellen explizit abnicken. Das macht ihm das Leben einfacher, weil er nicht so nicht aus Versehen implizit Quellen für Laufzeitfehler einbaut.

    Aber so sehr unterscheidet sich das doch nicht von Objective-C: Du kannst implizit von NSMutableString* nach NSString* casten, aber nicht andersrum - da will der Compiler auch von dir explizit abgenickt haben, dass du das wirklich so meinst.
    Multigrad - 360°-Produktfotografie für den Mac
  • Der Vergleich zieht nicht: Auf unterschiedliche Typen kannst du ja auch in Swift casten. Mich stört auch eher die Existenz von as als von as?/as!

    Dass man den dynamischen Fall auch mit einem Operator abdecken kann, zeigen ja ganz viele andere Sprachen. Eigentlich ist da as? problematisch. Ich caste auf einen Typ und weiß gar nicht, ob das geht. Klar, das kann aus theoretischer Sicht notwendig sein. In der Praxis zeigt es wahrscheinlich eher, dass ich die Typen meiner Objekte nicht unter Kontrolle habe. Falls das mal wirklich in einem von 1000000000000000000000000000000 Fällen notwendig sein sollte, sollte man vielleicht lieber mit einem expliziten if arbeiten.
    „Meine Komplikation hatte eine Komplikation.“
  • Michael schrieb:

    Ja, 5 lieferte in der SO-Q einen Fehler. Vermutlich weil Swift 1.2 verwendet wurde. In dem Fall liefert aber 2 von oben ebenfalls einen Fehler. In Swift 1.2 hat sich am Casten eben was geändert:

    Quellcode

    1. // Gilt ab Swift 1.2
    2. let a = ObjectiveCClass.valueArray() // a inferiert zu Typ [AnyObject]!, ein Array mit irgendwelchen Objekten
    3. let b = ObjectiveCClass.valueArray() as! [NSValue] // b inferiert zu Typ [NSValue], ein Array mit Objekten vom Typ NSValue
    4. let c = ObjectiveCClass.valueArray() as? [NSValue] // c inferiert zu Typ [NSValue]?, ein Optional Array mit Objekten vom Typ NSValue
    5. let x = a[0] as! NSValue // castet das erste Element aus dem Array zum Typ NSValue
    6. let y = a[0] as? NSValue // castet das erste Element aus dem Array zu einem Optional NSValue (NSValue?)

    Ist ein klein wenig anders, aber immer noch ohne Ungereimtheiten.
    Okay, erst einmal bin ich ja beruhigt, dass das doch ein Bug war.

    Aber ich sehe immer noch eine Ungereimtheit:
    Wenn

    let a = ObjectiveCClass.valueArray()

    zu [AnyKey]! inferiert, wieso muss ich dann mit as! casten. Ich teile ihm hier doch eine Information mit, die der Compiler bereits hat, so das as ausreichen solle. Aber vielleicht komme ich jetzt völlig mit den Versionen durcheinander.
    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"?
  • zerm schrieb:

    macmoonshine schrieb:

    Naja, Swift ist meines Wissens bislang die erste Sprache, die mehrere Cast-Operatoren anbietet

    C++ hat static_cast, reinterpret_cast und dynamic_cast ;) (..und const_cast, sowie C-style-cast-brrrr)
    Er sagt "Sprache". Er sagte nicht "südtexanisches Kauderwelsch".
    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"?
  • mattik schrieb:

    macmoonshine schrieb:

    Ja genau: Aber wieso muss ich das als Programmierer unterscheiden? Der Compiler könnte sich ja auch automatisch darum kümmern. Nenn' mich verrückt, aber ich habe immer noch die komische Vorstellung, dass Computer und Programme das Leben einfacher machen sollen.

    Natürlich könnte der Compiler das automatisch machen - das ist reine Absicht. Der Programmierer soll diese möglichen Bruchstellen explizit abnicken. Das macht ihm das Leben einfacher, weil er nicht so nicht aus Versehen implizit Quellen für Laufzeitfehler einbaut.

    Aber so sehr unterscheidet sich das doch nicht von Objective-C: Du kannst implizit von NSMutableString* nach NSString* casten, aber nicht andersrum - da will der Compiler auch von dir explizit abgenickt haben, dass du das wirklich so meinst.
    Das ist etwas anderes, weil Klassenbasiert. Ein Objekt vom Typen NSMutableString *ist* ein Objekt vom Typen NSString.
    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:

    Okay, erst einmal bin ich ja beruhigt, dass das doch ein Bug war.

    Das kannst du gerne glauben, aber der SO-Post enthält doch zu wenig Informationen, um da ein Fehlverhalten des Compilers abzuleiten. Ich konnte den angeblichen „Bug“ jedenfalls nicht reproduzieren. Egal mit welchem Compiler.

    Amin Negm-Awad schrieb:

    Aber ich sehe immer noch eine Ungereimtheit:
    Wenn

    let a = ObjectiveCClass.valueArray()

    zu [AnyKey]! inferiert,

    Das tut es, weil die Objective-C Methode unter Umständen auch nur ein nil, statt ein Array zurückgeben kann.

    Amin Negm-Awad schrieb:

    wieso muss ich dann mit as! casten. Ich teile ihm hier doch eine Information mit, die der Compiler bereits hat, so das as ausreichen solle.

    Weil der Cast schief gehen kann und zwar auch, wenn 'a' nicht nil ist. Der Compiler weiß zur Übersetzungszeit nicht, welchen Typ die Objekte in dem Array haben. Der Typ [AnyObject]! ist ja ein „implicit unwrapped array“, was bedeutet, dass du beim Zugriff auf das Array, dieses nicht erst noch unwrappen musst.