Stampa variabile opzionale

Sto provando con queste linee di codice

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()) 

Sopra il codice produce come segue

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

La mia domanda è: perché lì è opzionale (18), come posso rimuovere la stampa opzionale e solo

 Daniel is 18 years old. 

Devi capire cosa sia veramente un optional. Molti principianti di Swift pensano var age: Int? significa che l’età è un Int che può avere o meno un valore. Ma significa che l’età è un Opzionale che può o meno tenere un Int.

All’interno della funzione description() non si stampa l’Int, ma si stampa Opzionale. Se si desidera stampare Int, è necessario scartare l’opzione. Puoi usare “binding opzionale” per scartare un Optional:

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

Se si è certi che l’object opzionale contenga un object, è ansible utilizzare “unwrapping forzato”:

 let a = age! 

O nel tuo esempio, dal momento che hai già un test per nil nella funzione description, puoi semplicemente cambiarlo in:

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

Un optional significa che Swift non è del tutto sicuro se il valore corrisponde al tipo: ad esempio, Int? significa che Swift non è del tutto sicuro che il numero sia un Int.

Per rimuoverlo, ci sono tre metodi che potresti impiegare.

1) Se sei assolutamente sicuro del tipo, puoi usare un punto esclamativo per forzarlo a scartarlo, come questo:

 // Here is an optional variable: var age: Int? // Here is how you would force unwrap it: var unwrappedAge = age! 

Se si forza scartare un opzionale ed è uguale a zero, si può verificare questo errore di crash:

inserisci la descrizione dell'immagine qui

Questo non è necessariamente sicuro, quindi ecco un metodo che potrebbe prevenire crash nel caso in cui non si è certi del tipo e del valore:

I metodi 2 e 3 proteggono da questo problema.

2) Opzionale implicitamente non imballato

  if let unwrappedAge = age { // continue in here } 

Notare che il tipo unwrapped è ora Int , piuttosto che Int? .

3) La dichiarazione di guardia

  guard let unwrappedAge = age else { // continue in here } 

Da qui, puoi andare avanti e usare la variabile unwrapped. Assicurati solo di forzare lo scartare (con un!), Se sei sicuro del tipo di variabile.

Buona fortuna con il vostro progetto!

Per scopi di test / debug, spesso desidero generare degli optionals come stringhe senza dover sempre verificare i valori nil , quindi ho creato un operatore personalizzato.

Ho migliorato ulteriormente le cose dopo aver letto questa risposta in un’altra domanda .

 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?) -> String { return x.unwrappedString } 

Ovviamente l’operatore (e i suoi attributi) può essere modificato a tuo piacimento, oppure puoi invece farne una funzione. In ogni caso, questo ti permette di scrivere un codice semplice come questo:

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

L’integrazione dell’idea del protocollo dell’altro ragazzo lo rendeva tale che funziona anche con gli optionals nidificati, che si verificano spesso quando si usa il concatenamento opzionale. Per esempio:

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

Aggiornare

Basta usare me.age ?? "Unknown age!" me.age ?? "Unknown age!" . Funziona in 3.0.2.

Vecchia risposta

Senza forzare lo scartare (nessun segnale mach / crash se nullo) un altro bel modo per farlo sarebbe:

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

result["ip"] ?? "unavailable" result["ip"] ?? "unavailable" dovrebbe avere anche il lavoro, ma non lo è, almeno nel 2.2

Ovviamente, sostituisci “non disponibile” con qualsiasi cosa ti si addice: “nil”, “non trovato” ecc

Per scartare l’ age! utilizzo opzionale age! invece di age . Attualmente stai stampando un valore opzionale che potrebbe essere nil . Ecco perché è stato avvolto con Optional .

In swift Optional è qualcosa che può essere nil in alcuni casi. Se sei sicuro al 100% che una variable avrà sempre un valore e non restituirà nil l’add ! con la variabile per forzarlo a scartarlo.

In altri casi, se non si è molto sicuri del valore, aggiungere un blocco if let o if let per assicurarsi che il valore esista altrimenti potrebbe causare un arresto anomalo.

Per if let blocchi:

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

Per la dichiarazione di guard :

guard è una struttura condizionale per restituire il controllo se la condizione non è soddisfatta.

Preferisco usare guard over if let bloccare in molte situazioni in quanto ci permette di restituire la function se non esiste un valore particolare. Come quando esiste una funzione in cui una variabile è parte integrante dell’esistente, possiamo verificarla in dichiarazione di guardia e il suo ritorno non esiste. ie;

 guard let abc = any_variable else { return } 

Se esiste una variabile, possiamo usare ‘abc’ nella funzione al di fuori dell’ambito di guardia.

age è facoltativo: Optional quindi se lo si confronta con nil restituisce false ogni volta se ha un valore o se non lo è. È necessario scartare l’opzionale per ottenere il valore.

Nel tuo esempio non sai che contiene alcun valore, quindi puoi usare questo invece:

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

Ho fatto questo per stampare il valore di string (proprietà) da un altro controller di visualizzazione.

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)") 

Risultato:

 The Value of String is I am iOS Developer 

Controlla la dichiarazione di sicurezza:

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

Stavo ricevendo l’opzionale (“String”) nelle mie celle tableview.

La prima risposta è grande. E mi ha aiutato a capirlo. Ecco cosa ho fatto, per aiutare gli esordienti là fuori come me.

Dato che sto creando un array nel mio object personalizzato, so che avrà sempre elementi nella prima posizione, quindi posso forzarlo a scartarlo in un’altra variabile. Quindi utilizzare quella variabile per stampare, o nel mio caso, impostare il testo della cella tableview.

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

Sembra così semplice ora, ma mi ci è voluto un po ‘per capire.

Quando si ha un valore predefinito:

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

o quando il nome è facoltativo:

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

Questa non è la risposta esatta a questa domanda, ma una ragione per questo tipo di problema. Nel mio caso, non ero in grado di rimuovere Optional da una stringa con “if let” e “guard let”.

Quindi usa AnyObject invece di Any per rimuovere facoltativo da una stringa in swift.

Si prega di fare riferimento al link per la risposta.

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