Impresión de variable opcional

Estoy intentando con estas líneas de código

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

El código anterior produce como sigue

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

Mi pregunta es por qué hay Opcional (18) allí, ¿cómo puedo eliminar la impresión opcional y solo?

 Daniel is 18 years old. 

Tienes que entender qué es realmente un Opcional. Muchos principiantes de Swift piensan en la var age: Int? significa que la edad es un Int que puede o no tener un valor. Pero significa que la edad es un Opcional que puede o no contener un Int.

Dentro de su función description() no imprime el Int, sino que imprime el Opcional. Si desea imprimir el Int, debe desplegar el Opcional. Puede usar “enlace opcional” para desenvolver un Opcional:

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

Si está seguro de que el Opcional contiene un objeto, puede usar “desenvolvimiento forzado”:

 let a = age! 

O en su ejemplo, dado que ya tiene una prueba para nil en la función de descripción, puede simplemente cambiarla a:

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

Una opción significa que Swift no está completamente seguro de si el valor corresponde al tipo: por ejemplo, Int? significa que Swift no está del todo seguro de si el número es un Int.

Para eliminarlo, hay tres métodos que puede emplear.

1) Si está absolutamente seguro del tipo, puede usar un signo de exclamación para forzarlo a desenvolver, así:

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

Si fuerza desenvolver una opción opcional y es igual a cero, puede encontrar este error de locking:

enter image description here

Esto no es necesariamente seguro, así que aquí hay un método que podría evitar colisiones en caso de que no esté seguro del tipo y valor:

Los métodos 2 y 3 protegen contra este problema.

2) El opcional implícitamente desempaquetado

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

Tenga en cuenta que el tipo desenvuelto ahora es Int , en lugar de Int? .

3) La statement de guardia

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

Desde aquí, puede continuar y usar la variable desenvuelta. Asegúrese de forzar el desplegado (con an!), Si está seguro del tipo de la variable.

¡Buena suerte con tu proyecto!

Con fines de prueba / depuración, a menudo quiero mostrar los elementos adicionales como cadenas sin tener que probar siempre los valores nil , así que creé un operador personalizado.

Mejoré las cosas aún más después de leer esta respuesta en otra pregunta .

 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 } 

Obviamente, el operador (y sus atributos) pueden ajustarse a su gusto, o puede hacerlo funcionar. De todos modos, esto te permite escribir un código simple como este:

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

La integración de la idea de protocolo del otro tipo hizo que esto funcione incluso con opciones anidadas, que a menudo ocurren cuando se utiliza el encadenamiento opcional. Por ejemplo:

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

Actualizar

Simplemente use me.age ?? "Unknown age!" me.age ?? "Unknown age!" . Funciona en 3.0.2.

Vieja respuesta

Sin fuerza desenvolver (ninguna señal mach / crash if nil) otra buena manera de hacer esto sería:

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

result["ip"] ?? "unavailable" result["ip"] ?? "unavailable" debería tener también trabajo, pero no es así, no en 2.2 al menos

Por supuesto, reemplace “no disponible” con lo que le convenga: “nulo”, “no encontrado”, etc.

Para desenvolver la age! uso opcional age! en lugar de age Actualmente está imprimiendo un valor opcional que podría ser nil . Es por eso que se envuelve con Optional .

En Swift Optional es algo que puede ser nil en algunos casos. Si está 100% seguro de que una variable tendrá algún valor siempre y no devolverá nada, ! añada ! con la variable para forzar desenvolverlo.

En otro caso, si no está muy seguro de su valor, agregue un bloque if let para asegurarse de que exista ese valor, de lo contrario, puede provocar un locking.

Para if let bloquear:

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

Para la statement del guard :

guard es una estructura condicional para devolver el control si no se cumple la condición.

Prefiero utilizar la función de guard if let bloquear en muchas situaciones, ya que nos permite devolver la function si no existe un valor en particular. Como cuando hay una función donde una variable es integral para existir, podemos verificarla en la statement de guardia y su devolución no existe. es decir;

 guard let abc = any_variable else { return } 

Si existe una variable, podemos usar ‘abc’ en la función fuera del scope del protector.

age es de tipo opcional: Optional por lo que si lo compara con nada, devuelve false cada vez si tiene un valor o si no lo tiene. Necesita desenvolver la opción para obtener el valor.

En su ejemplo, usted no sabe si contiene algún valor, así que puede usar esto en su lugar:

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

Hice esto para imprimir el valor de la cadena (propiedad) desde otro controlador de vista.

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

Resultado:

 The Value of String is I am iOS Developer 

Echa un vistazo a la statement del guard :

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

Obtenía el Opcional (“Cadena”) en mis celdas de vista de tabla.

La primera respuesta es genial. Y me ayudó a resolverlo. Esto es lo que hice, para ayudar a los novatos como yo.

Como estoy creando una matriz en mi objeto personalizado, sé que siempre tendrá elementos en la primera posición, por lo que puedo obligar a desenvolverlo en otra variable. Luego use esa variable para imprimir, o en mi caso, configure el texto de la celda de vista de tabla.

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

Parece tan simple ahora, pero me tomó un tiempo darme cuenta.

Cuando tiene un valor predeterminado:

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

o cuando el nombre es opcional:

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

Esta no es la respuesta exacta a esta pregunta, sino una razón para este tipo de problema. En mi caso, no pude eliminar Opcional de una Cadena con “if let” y “guard let”.

Así que use AnyObject en lugar de Any para eliminar opcionalmente de una cadena en swift.

Por favor, consulte el enlace para la respuesta.

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