545 Stimmen

Was bedeutet ein Ausrufezeichen in der Swift-Sprache?

Der Leitfaden zur Swift-Programmiersprache hat das folgende Beispiel:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { println("\(name) wird deinitialisiert") }
}

class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    var tenant: Person?
    deinit { println("Apartment Nr. \(number) wird deinitialisiert") }
}

var john: Person?
var number73: Apartment?

john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)

// Aus dem Leitfaden "The Swift Programming Language" von Apple (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html)

Dann, wenn das Apartment der Person zugewiesen wird, benutzen sie ein Ausrufezeichen, um die Instanz "auszupacken":

john!.apartment = number73

Was bedeutet es, eine Instanz "auszupacken"? Warum ist es notwendig? Wie unterscheidet es sich davon, einfach folgendes zu tun:

john.apartment = number73

Ich bin ganz neu in der Swift-Sprache. Versuche nur, die Grundlagen zu verstehen.

UPDATE:
Das große Puzzlestück, das mir fehlte (nicht direkt in den Antworten angegeben - zumindest nicht zum Zeitpunkt des Verfassens dieses Beitrags), ist, dass wenn man Folgendes tut:

var john: Person?

das NICHT bedeutet, dass "john vom Typ Person ist und vielleicht nil sein könnte", wie ich ursprünglich dachte. Ich habe einfach missverstanden, dass Person und Person? vollständig separate Typen sind. Sobald ich das verstanden hatte, ergaben alle anderen ?, ! Verwirrungen und die großartigen Antworten unten viel mehr Sinn.

1voto

Ashish Pisey Punkte 1425

Eine optionale Variable kann einen Wert enthalten oder auch nicht

Fall 1: var myVar:String? = "Etwas"

Fall 2: var myVar:String? = nil

Wenn du jetzt myVar! abfragst, sagst du dem Compiler, einen Wert zurückzugeben. Im Fall 1 wird es "Etwas" zurückgeben

Im Fall 2 wird es abstürzen.

Das Ausrufezeichen zwingt den Compiler, einen Wert zurückzugeben, selbst wenn keiner vorhanden ist. Deswegen der Name Force Unwrapping.

0voto

jeff ayan Punkte 739
 Einfach das optionale Variable erlaubt das Speichern von nil.

var str : String? = nil

str = "Daten"

Um das optionale in den spezifischen Datentyp umzuwandeln, entpacken wir die Variable mit dem Schlüsselwort "!"

func get(message : String){
   return
}

get(message : str!)  // Entpackt zur Übergabe als String

-1voto

mfaani Punkte 28161

FRAGEN SIE SICH SELBST

  • Hat der Typ Person? ein Apartment Mitglied/Eigenschaft? ODER
  • Hat der Typ Person ein Apartment Mitglied/Eigenschaft?

Wenn Sie diese Frage nicht beantworten können, dann lesen Sie weiter:

Um zu verstehen, benötigen Sie möglicherweise ein sehr grundlegendes Verständnis von <strong>Generics</strong>. Siehe <a href="https://www.raywenderlich.com/115960/swift-tutorial-introduction-to-generics" rel="nofollow noreferrer">hier</a>. Viele Dinge in Swift werden unter Verwendung von Generics geschrieben. Optionale eingeschlossen

Der folgende Code stammt aus diesem Stanford-Video. Ich empfehle Ihnen dringend, die ersten 5 Minuten anzusehen

Ein Optional ist ein Enum mit nur 2 Fällen

enum Optional{
    case None
    case Some(T)
}

let x: String? = nil // bedeutet eigentlich:

let x = Optional.None

let x :String? = "hallo" // bedeutet eigentlich:

let x = Optional.Some("hallo")

var y = x! // bedeutet eigentlich:

switch x {
case .Some(let value): y = value
case .None: // Wirft eine Ausnahme
}

Optionale Bindung:

let x:String? = etwas
if let y = x {
    // etwas mit y machen
}
//Bedeutet eigentlich:

switch x{
case .Some(let y): print(y) // oder was auch immer Sie sonst noch verwenden möchten
case .None: break
}

Wenn Sie sagen var john: Person? meinen Sie eigentlich so etwas:

enum Optional{
case .None
case .Some(Person)
}

Hat das obige Enum eine Eigenschaft namens Apartment? Sehen Sie es irgendwo? Es ist nicht vorhanden! Allerdings, wenn Sie es unwrappen, d.h. Person! machen, dann können Sie ... was es unter der Haube macht, ist: Optional.Some(Person(name: "John Appleseed"))


Hätten Sie var john: Person anstelle von: var john: Person? definiert, dann hätten Sie den ! nicht mehr benötigt, da Person selbst ein Mitglied von Apartment hat


Als zukünftige Diskussion, warum es manchmal nicht empfehlenswert ist, ! zum Entpacken zu verwenden, siehe diese Q&A

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X