Optionele variabele afdrukken

Ik probeer het met deze regels code

class Student {
    var name: String
    var age: Int?
    init(name: String) {
        self.name = name
    }
    func description() -> String {
        return age != nil ? "\(name) is \(age) years old." : "\(name) hides his age."
    }
}
var me = Student(name: "Daniel")
println(me.description())
me.age = 18
println(me.description())

Bovenstaande code produceert als volgt

Daniel hides his age.
Daniel is Optional(18) years old.

Mijn vraag is waarom er Optioneel (18) is, hoe kan ik de optionele verwijderen en gewoon afdrukken

Daniel is 18 years old.

Antwoord 1, autoriteit 100%

Je moet begrijpen wat een Optioneel werkelijk is. Veel Swift-beginners denken dat var age: Int?betekent dat age een Int is die al dan niet een waarde heeft. Maar het betekent dat leeftijd een Optioneel is die al dan niet een Int.

Binnen uw functie description()drukt u niet de Int af, maar in plaats daarvan drukt u de Optioneel af. Als u de Int wilt afdrukken, moet u de Optioneel uitpakken. U kunt “optionele binding” gebruiken om een ​​Optioneel uit te pakken:

if let a = age {
 // a is an Int
}

Als u zeker weet dat de Optioneel een object bevat, kunt u “geforceerd uitpakken” gebruiken:

let a = age!

Of in uw voorbeeld, aangezien u al een test voor nul heeft in de beschrijvingsfunctie, kunt u deze gewoon wijzigen in:

func description() -> String {
    return age != nil ? "\(name) is \(age!) years old." : "\(name) hides his age."
}

Antwoord 2, autoriteit 9%

Om het te verwijderen, zijn er drie methoden die u kunt gebruiken.

  1. Als je absoluut zeker bent van het type, kun je een uitroepteken gebruiken om het geforceerd uit te pakken, zoals dit:

    // Hier is een optionele variabele:

    var leeftijd: Int?

    // Zo zou je het geforceerd uitpakken:

    var unwrappedAge = leeftijd!

Als u een optionele optie geforceerd uitpakt en deze is gelijk aan nul, kunt u deze crashfout tegenkomen:

voer hier de afbeeldingsbeschrijving in

Dit is niet per se veilig, dus hier is een methode die crashes kan voorkomen als u niet zeker bent van het type en de waarde:

Methoden 2 en drie beschermen tegen dit probleem.

  1. De impliciet onverpakte optie

    if let unwrappedAge = age {

    // ga hier verder

    }

Houd er rekening mee dat het uitgepakte type nu Intis, in plaats van Int?.

  1. De bewakerverklaring

    guard let unwrappedAge = age else {
    // ga hier verder
    }

Vanaf hier kunt u doorgaan en de onverpakte variabele gebruiken. Zorg ervoor dat u het uitpakken alleen forceert (met een !), als u zeker bent van het type variabele.

Veel succes met je project!


Antwoord 3, autoriteit 5%

Voor test-/foutopsporingsdoeleinden wil ik vaak optionals als strings uitvoeren zonder altijd te moeten testen op nil-waarden, dus heb ik een aangepaste operator gemaakt.

Ik heb de zaken nog verder verbeterd na het lezen van dit antwoord in een andere vraag.

fileprivate protocol _Optional {
    func unwrappedString() -> String
}
extension Optional: _Optional {
    fileprivate func unwrappedString() -> String {
        switch self {
        case .some(let wrapped as _Optional): return wrapped.unwrappedString()
        case .some(let wrapped): return String(describing: wrapped)
        case .none: return String(describing: self)
        }
    }
}
postfix operator ~? { }
public postfix func ~? <X> (x: X?) -> String {
    return x.unwrappedString
}

Het is duidelijk dat de operator (en zijn attributen) naar wens kunnen worden aangepast, of je kunt er in plaats daarvan een functie van maken. Hoe dan ook, dit stelt je in staat om eenvoudige code als volgt te schrijven:

var d: Double? = 12.34
print(d)     // Optional(12.34)
print(d~?)   // 12.34
d = nil
print(d~?)   // nil

Door het protocolidee van de andere man te integreren, werkt dit zelfs met geneste opties, die vaak voorkomen bij het gebruik van optionele ketens. Bijvoorbeeld:

let i: Int??? = 5
print(i)              // Optional(Optional(Optional(5)))
print("i: \(i~?)")    // i: 5

Antwoord 4, autoriteit 4%

Bijwerken

Gebruik gewoon me.age ?? "Unknown age!". Het werkt in 3.0.2.

Oud antwoord

Zonder geforceerd uitpakken (geen mach-signaal/crash indien nihil) zou een andere leuke manier om dit te doen zijn:

(result["ip"] ?? "unavailable").description.

result["ip"] ?? "unavailable"zou ook moeten werken, maar dat doet het niet, tenminste niet in 2.2

Natuurlijk, vervang “niet beschikbaar” door wat bij u past: “nul”, “niet gevonden” enz.


Antwoord 5, autoriteit 2%

Als u optioneel wilt uitpakken, gebruikt u age!in plaats van age. Momenteel drukt u een optionele waarde af die nilkan zijn. Daarom is het verpakt met Optional.


Antwoord 6, autoriteit 2%

In swift is Optionaliets dat in sommige gevallen nilkan zijn. Als je er 100% zeker van bent dat een variablealtijd een bepaalde waarde zal hebben en niet nilzal retourneren, voeg dan !toe met de variabele om het geforceerd uit te pakken .

In andere gevallen, als je niet zeker bent van de waarde, voeg dan een if letblock of guardtoe om er zeker van te zijn dat die waarde bestaat, anders kan dit leiden tot een crash.

Voor if letblokkeren:

if let abc = any_variable {
 // do anything you want with 'abc' variable no need to force unwrap now.
}

Voor guardverklaring:

guardis een voorwaardelijke structuur om de controle terug te geven als niet aan de voorwaarde wordt voldaan.

Ik gebruik liever guardboven if letblock in veel situaties, omdat het ons in staat stelt de functionterug te geven als een bepaalde waarde dat niet doet bestaan.
Net als wanneer er een functie is waarbij een variabele integraal bestaat, kunnen we ernaar zoeken in een guard-statement en de terugkeer ervan bestaat niet.
ik-e;

guard let abc = any_variable else { return }

Als een variabele bestaat, kunnen we ‘abc’ gebruiken in de functie buiten het bereik van de bewaking.


Antwoord 7, autoriteit 2%

ageis een optioneel type: Optional<Int>dus als je het vergelijkt met nul, retourneert het elke keer false als het een waarde heeft of niet. Je moet het optionele uitpakken om de waarde te krijgen.

In uw voorbeeld weet u niet of het een waarde bevat, dus u kunt dit in plaats daarvan gebruiken:

if let myAge = age {
    // there is a value and it's currently undraped and is stored in a constant
}
else {
   // no value
}

Antwoord 8, autoriteit 2%

Ik deed dit om de waarde van string (property) van een andere view-controller af te drukken.

ViewController.swift

var testString:NSString = "I am iOS Developer"

SecondViewController.swift

var obj:ViewController? = ViewController(nibName: "ViewController", bundle: nil)
print("The Value of String is \(obj!.testString)")

Resultaat:

The Value of String is I am iOS Developer

Antwoord 9, autoriteit 2%

Bekijk de guard-verklaring:

for student in class {
    guard let age = student.age else { 
        continue 
     }
    // do something with age
}

Antwoord 10, autoriteit 2%

Als je een standaardwaarde hebt:

print("\(name) is \(age ?? 0) years old")

of wanneer de naam optioneel is:

print("\(name ?? "unknown") is \(age) years old")


Antwoord 11

Ik kreeg de Optioneel (“String”) in mijn tableview-cellen.

Het eerste antwoord is geweldig. En hielp me er achter te komen. Dit is wat ik deed, om de rookies zoals ik te helpen.

Omdat ik een array aan het maken ben in mijn aangepaste object, weet ik dat er altijd items op de eerste positie staan, dus ik kan het geforceerd uitpakken in een andere variabele. Gebruik die variabele vervolgens om af te drukken, of in mijn geval, stel in op de celtekst van de tabelweergave.

let description = workout.listOfStrings.first!
cell.textLabel?.text = description

Het lijkt nu zo eenvoudig, maar het kostte me wat tijd om erachter te komen.


Antwoord 12

Dit is niet het exacte antwoord op deze vraag, maar een reden voor dit soort problemen.
In mijn geval,
Ik kon Optioneel niet van een string verwijderen met “if let” en “guard let”.

Gebruik dus AnyObjectin plaats van Anyom optioneel in swift uit een tekenreeks te verwijderen.

Raadpleeg de link voor het antwoord.

https://stackoverflow.com/a/51356716/8334818


Antwoord 13

Als je gewoon van strings als Optional(xxx)af wilt en in plaats daarvan xxxof nilwilt krijgen als je ergens waarden afdrukt (zoals logs), kunt u de volgende extensie aan uw code toevoegen:

extension Optional {
    var orNil: String {
        if self == nil {
            return "nil"
        }
        return "\(self!)"
    }
}

Vervolgens de volgende code:

var x: Int?
print("x is \(x.orNil)")
x = 10
print("x is \(x.orNil)")

geeft je:

x is nil
x is 10

PS. Naamgeving van eigenschappen (orNil) is natuurlijk niet de beste, maar ik kan niets duidelijkers bedenken.


Antwoord 14

Met de volgende code kunt u deze afdrukken of een standaardwaarde afdrukken. Dat is wat XCode over het algemeen aanbeveelt denk ik

var someString: String?
print("Some string is \(someString ?? String("Some default"))")

Other episodes