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

  • Amin Negm-Awad schrieb:

    Es funktionierte doch nicht?!

    Doch es funktioniert.

    Amin Negm-Awad schrieb:

    Und bei [AnyKey] as [NSVallue] musste der Typ ja auch kein as! nehmen.

    Musste er nicht? Kann ich aus dem Stackoverflow Beitrag nicht erkennen.

    Amin Negm-Awad schrieb:

    Die Frage bleibt doch, warum das mal so und mal so ist.

    Es ist nicht mal so und mal so. Bisher geht es mit as und ab Swift 1.2 nur noch mit as! oder as?. Ich habe mir inzwischen mal die Beta mit Swift 1.2 geladen. Siehe Screenshots.
    Dateien
    • as.png

      (59,16 kB, 218 mal heruntergeladen, zuletzt: )
    • as!.png

      (63,96 kB, 218 mal heruntergeladen, zuletzt: )
  • Michael schrieb:

    Amin Negm-Awad schrieb:

    Es funktionierte doch nicht?!

    Doch es funktioniert.

    Amin Negm-Awad schrieb:

    Und bei [AnyKey] as [NSVallue] musste der Typ ja auch kein as! nehmen.

    Musste er nicht? Kann ich aus dem Stackoverflow Beitrag nicht erkennen.

    Amin Negm-Awad schrieb:

    Die Frage bleibt doch, warum das mal so und mal so ist.

    Es ist nicht mal so und mal so. Bisher geht es mit as und ab Swift 1.2 nur noch mit as! oder as?. Ich habe mir inzwischen mal die Beta mit Swift 1.2 geladen. Siehe Screenshots.
    In der Lösung wurde as? verwendet.

    Wenn das inzwischen so ist, dann war es doch ein Bug bei ihm!?

    Und immerhin verstehe ich immer noch nicht, das ist untergegangen, warum [AnyKey] inseriert wird, nicht [AnyKey?], der Compiler also ganz genau weiß, dass da kein nil kommt und man dennoch ? oder ! verwenden muss.
    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"?
  • Optional ist ja jetzt universal.
    ? heißt also nicht 'NSValue oder nil' sondern 'NSVale oder irgendwas Anderes inklusive nil'

    Das ist dann natürlich blöd.
    ! heißt jetzt 'NSValue oder irgendwas Anderes exklusive nil', weil in dem Zusammenhang (@NonNil) kein nil zurückgegeben werden kann.
    Aber es kann natürlich ein NSColor da drin liegen, das sich partout nicht auf NSVale casten lässt.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Amin Negm-Awad schrieb:

    Und immerhin verstehe ich immer noch nicht, das ist untergegangen, warum [AnyKey] inseriert wird, nicht [AnyKey?], der Compiler also ganz genau weiß, dass da kein nil kommt und man dennoch ? oder ! verwenden muss.

    [AnyObject] bedeutet, es ist ein Array mit Objekten drin, Klasse unbekannt aber garantiert nicht nil. Das ist ja richtig, denn wir wissen ja, NSArray kann kein nil enthalten.
    as! [NSValue]castet auf ein Array, welches NSValue Objekte enthält, aber garantiert kein nil. Schlägt der Cast zur Laufzeit fehl, gibt es einen Programmabsturz.
    as? [NSValue] castet auf ein Optional Array, welches NSValue Objekte enthält, aber garantiert kein nil. Zur Laufzeit musst du per if let... prüfen, ob der Cast funktioniert hat.
  • Michael schrieb:


    as! [NSValue]castet auf ein Array, welches NSValue Objekte enthält, aber garantiert kein nil. Schlägt der Cast zur Laufzeit fehl, gibt es einen Programmabsturz.
    as? [NSValue] castet auf ein Optional Array, welches NSValue Objekte enthält, aber garantiert kein nil. Zur Laufzeit musst du per if let... prüfen, ob der Cast funktioniert hat.


    Wozu brauchst man diese Differenzierung? Mir fällt da gerade keine Anwendung ein. Im ersten Fall stürzt das Programm ab, wenn der Cast fehl schlägt und im zweiten Fall kann man nicht sicher sein, ob der Cast erfolgreich war. Not und Elend?
  • Michael schrieb:

    Amin Negm-Awad schrieb:

    Und immerhin verstehe ich immer noch nicht, das ist untergegangen, warum [AnyKey] inseriert wird, nicht [AnyKey?], der Compiler also ganz genau weiß, dass da kein nil kommt und man dennoch ? oder ! verwenden muss.

    [AnyObject] bedeutet, es ist ein Array mit Objekten drin, Klasse unbekannt aber garantiert nicht nil. Das ist ja richtig, denn wir wissen ja, NSArray kann kein nil enthalten.
    as! [NSValue]castet auf ein Array, welches NSValue Objekte enthält, aber garantiert kein nil. Schlägt der Cast zur Laufzeit fehl, gibt es einen Programmabsturz.
    as? [NSValue] castet auf ein Optional Array, welches NSValue Objekte enthält, aber garantiert kein nil. Zur Laufzeit musst du per if let... prüfen, ob der Cast funktioniert hat.
    Genau

    Und wieso hat bei ihm der Compiler das abgelehnt und das andere nicht? Und wieso muss man es jetzt unterschiedlich behandeln? Es geht mir nicht darum, wie es gerade mal für die nächsten zwei Wochen ist, sondern wieso es unterschiedlich ist.

    Wie kann ein Compiler meinen, dass es richtig ist aus "Feld von irgendwas" ein "Feld von Werten" zu machen, es aber nicht richtig ist, aus einem Element eines Feldes von Irgendetwas ein Element von Werten zu machen. Das ist doch offensichtlich gleichbedeutend.

    Und noch viel wichtiger: Wieso hat der Compiler(!) dazu offenkundig schon zwei unterschiedliche Meinungen vertreten und wieso werden hier offenkundig 4 verschiedene Meinungen dazu vertreten? Das ist ja jetzt nichts Ungewöhnliches, sondern Alltag in Cocoa.
    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:

    Michael schrieb:

    Amin Negm-Awad schrieb:

    Und immerhin verstehe ich immer noch nicht, das ist untergegangen, warum [AnyKey] inseriert wird, nicht [AnyKey?], der Compiler also ganz genau weiß, dass da kein nil kommt und man dennoch ? oder ! verwenden muss.

    [AnyObject] bedeutet, es ist ein Array mit Objekten drin, Klasse unbekannt aber garantiert nicht nil. Das ist ja richtig, denn wir wissen ja, NSArray kann kein nil enthalten.
    as! [NSValue]castet auf ein Array, welches NSValue Objekte enthält, aber garantiert kein nil. Schlägt der Cast zur Laufzeit fehl, gibt es einen Programmabsturz.
    as? [NSValue] castet auf ein Optional Array, welches NSValue Objekte enthält, aber garantiert kein nil. Zur Laufzeit musst du per if let... prüfen, ob der Cast funktioniert hat.
    Genau

    Und wieso hat bei ihm der Compiler das abgelehnt und das andere nicht?

    Ich sehe da nur ein Zeile Code, die der Compiler ihm abgelehnt hat:
    let myValue = myArray[0] as NSValue // Cast error since AnyObject cannot be cast to NSValue
    Welche andere Variante hat der Compiler bei ihm nicht abgelehnt?

    Amin Negm-Awad schrieb:

    Und wieso muss man es jetzt unterschiedlich behandeln? Es geht mir nicht darum, wie es gerade mal für die nächsten zwei Wochen ist, sondern wieso es unterschiedlich ist.

    Es ist nicht unterschiedlich!
    let array = ObjectiveCClass.valueArray() as [NSValue] und let object = array[0] as NSValue funktioniert mit dem aktuellen Compiler, aber ab Swift 1.2 funktioniert beides nicht mehr!
    let array = ObjectiveCClass.valueArray() as! [NSValue] und let object = array[0] as! NSValue funktioniert erst ab Swift 1.2 und da auch nur noch so!
    let array = ObjectiveCClass.valueArray() as? [NSValue] und let object = array[0] as? NSValue funktioniert in jeder Version. Daran hat sich nichts mit Swift 1.2 geändert.

    Amin Negm-Awad schrieb:

    Wie kann ein Compiler meinen, dass es richtig ist aus "Feld von irgendwas" ein "Feld von Werten" zu machen, es aber nicht richtig ist, aus einem Element eines Feldes von Irgendetwas ein Element von Werten zu machen. Das ist doch offensichtlich gleichbedeutend.

    Das meint kein Compiler. Weder der aktuelle, noch der kommende Compiler. Der kommende Compiler macht nur einen Unterschied dabei, ob er einen Cast zur Übersetzungszeit garantieren kann oder nicht.

    Amin Negm-Awad schrieb:

    Und noch viel wichtiger: Wieso hat der Compiler(!) dazu offenkundig schon zwei unterschiedliche Meinungen vertreten

    Die Frage kann dir nur Apple beantworten.

    Amin Negm-Awad schrieb:

    und wieso werden hier offenkundig 4 verschiedene Meinungen dazu vertreten?

    Das könnte eventuell daran liegen, dass sich einige mit dem Thema nur theoretisch befassen und andere das auch mal mit den echten Compilern ausprobieren. ;)
  • Ich spreche von dem Code in der Antwort, der akzeptiert wurde. Und das wurde ganz echt ausprobiert.

    Aber eine gewisse innere Logik darf man doch ohne Ausprobieren erwarten, oder? Liest sich ja auch schlecht im Handbuch: "Probiere es so oder so irgendwas wird schon funktionieren."
    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:

    Ich spreche von dem Code in der Antwort, der akzeptiert wurde. Und das wurde ganz echt ausprobiert.

    Der Code in der Antwort ist nur eine mögliche Lösung, aber nicht die Einzige. Du vergleichst hier also das as mit as?. Das sind zwei unterschiedliche Casts. Das sich zwei unterschiedliche Casts unterschiedlich verhalten halte ich jetzt nicht für ungewöhnlich, sondern normal.

    Amin Negm-Awad schrieb:

    Aber eine gewisse innere Logik darf man doch ohne Ausprobieren erwarten, oder? Liest sich ja auch schlecht im Handbuch: "Probiere es so oder so irgendwas wird schon funktionieren."

    Im Handbuch steht es ja korrekt drin (allerdings noch nicht für Swift 1.2, das steht im Moment nur im Swift-Blog).
  • Das ist klar, dass sich das generell unterschiedlich verhalten kann. Wie aber bereits in der Frage steht und von mir hier wiederholt wurde, inseriert der Compiler das in diesem Falle ja zutreffend auf [AnyKey]. Dann kann es auf das as? nicht mehr ankommen. Entweder er inferiert falsch oder er erwartet zu viel Information. Siehe noch einmal oben.
    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"?
  • Quellcode

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

    Das ist der aktuelle Stand der Dinge. Ich sehe da jetzt keine Ungereimtheit.
  • Dann war das eben doch ein Bug. Denn 5 lieferte ja in der SO-Q einen Fehler:

    Quellcode

    1. let myArray = AnObjectiveCClass.myAwesomeFunction()
    2. let myValue = myArray[0] as NSValue // Cast error since AnyObject cannot be cast to NSValue
    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"?
  • 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.
  • So ganz ist mir der Sinn von zwei unterschiedlichen Operatoren nicht klar: Ob ein Cast immer funktioniert oder potentiell schiefgehen kann, kann doch der Swift-Compiler entscheiden. Der will ja schließlich überall wissen, welche Typen die Variablen haben. Warum muss er den Programmierer noch damit behelligen?
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    Warum muss er den Programmierer noch damit behelligen?

    Weil die Swift–Objective-C–Integration nach wie vor Grütze ist, deshalb.
    Und vermutlich wird die auch nicht besser, solange Cocoa auf Objective-C basiert.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • macmoonshine schrieb:

    So ganz ist mir der Sinn von zwei unterschiedlichen Operatoren nicht klar: Ob ein Cast immer funktioniert oder potentiell schiefgehen kann, kann doch der Swift-Compiler entscheiden. Der will ja schließlich überall wissen, welche Typen die Variablen haben. Warum muss er den Programmierer noch damit behelligen?

    Naja, das kann der Compiler nicht immer aus den Typen herausbekommen - statische Codeanalyse kann eine Menge, aber nicht alles. Manchmal ergeben sich die Laufzeitbedingungen aus einem Algorithmus oder aus externen Contracts. Auch wenn ich gerne über Swift meckern würde finde ich die ?- und !-Sache vom Prinzip eigentlich ganz ok und pragmatisch:

    ohne : Lieber Compiler, bitte mach so gut du kannst. Was geht statisch, den Rest zur Laufzeit.
    ? : Lieber Compiler, bitte mach' das hier zur Laufzeit nur wenn es dann gültig ist.
    ! : Lieber Compiler, bitte mach keine Laufzeitdynamik. Selbst wenn du das nicht wissen kannst: Ich, der Programmierer, garantiere dir, dass es immer gültig ist. Wenn ich mich irre, ist das definitiv ein Programmierfehler. Das Programm darf dann gerne abstürzen.

    Was davon syntaktisch und semantisch korrekt ist sollte der Compiler entscheiden können. Über Bugs im Compiler sowie Details und Konsequenzen in besonderen Fällen kann man sich sicherlich streiten, aber das ist so ziemlich bei allen Features aller Sprachen so. Darüber, dass Swift noch weit von der Brauchbarkeit entfernt ist, müssen wir wahrscheinlich nicht streiten.
    Multigrad - 360°-Produktfotografie für den Mac