Si quiero definir un typealias para un Diccionario, que acepta String como clave, y String para el valor, pero también quiero que acepte nil, ¿Cuál de estas definiciones es correcta?

typealias dictString = Dictionary<String, String?>

O

typealias dictString = Dictionary<String, String>

O

typealias dictString = [String:String?]

O

typealias dictString = [String:String]

Debido a que uso el primero, y ahora cada vez que quiero desenvolver un valor, necesito desenvolverlo dos veces (por ejemplo, dict["name"]!!), así que comencé a preguntarme si realmente necesito agregar el signo de interrogación o no (pero Necesito el diccionario para poder tomar un valor nulo). Gracias.

2
Chen Li Yong 14 feb. 2017 a las 11:09

2 respuestas

La mejor respuesta

El segundo y el cuarto están bien.

No es necesario que el valor sea opcional en la mayoría de los casos. Puede establecer el valor de una clave en nil incluso si no declaró el valor como un tipo opcional:

var dict = [String: String]()
dict["Hello"] = nil

Y cuando accede a "Hello", devuelve nil. ¡Fantástico!

De hecho, establecer el valor de una clave en nil significa "eliminar la clave". Esto puede causar resultados inesperados si no lo sabe.

Por ejemplo,

var dict = [String: String]()
dict["Hello"] = nil
print(dict.keys.contains("Hello"))

Imprime false.

Si necesita verificar si existe una clave incluso si su valor es nil, entonces debe hacer que el valor sea un tipo opcional.

5
Sweeper 14 feb. 2017 a las 08:21

Un diccionario devolverá nil para cualquier clave que no esté presente. Ahora, si desea poder tener la clave presente pero tener el valor nulo, entonces la versión 1 y 3 son el camino a seguir y mantiene el doble desenvolvimiento. De lo contrario, use 2 o 4.

Actualizar

Ejemplo:

Versiones 1 y 3:

typealias DictString = Dictionary<String, String?> // or [String: String?]
var myDict: DictString = ["MyKey1": "MyVal1", "MyKey2": nil]
var value1: String? = myDict["MyKey1"]! // This is an Optional String so you'd need to unwrap it
var value2: String? = myDict["MyKey2"]! // This will return nil

Versiones 2 y 4:

typealias DictString = Dictionary<String, String> // or [String: String]
var myDict: DictString = ["MyKey1": "MyVal1"]
var value1: String? = myDict["MyKey1"] // This is an Optional String so you'd need to unwrap it
var value2: String? = myDict["MyKey2"] // This will return nil

Ahora la diferencia entre los dos es que el primer caso realmente almacena las claves. Entonces, si alguna vez haces esto:

var allKeys: [String] = Array(myDict.keys)

Obtendrás dos resultados diferentes:

  • 1 y 3: allKeys será ["MyKey1", "MyKey2"]

  • 2 y 4: allKeys será ["MyKey1"]

P.S: una buena práctica es utilizar mayúsculas para los nombres de los tipos. Por lo tanto, sugeriría que cambie su typealias a DictString.

1
Mihai Fratu 14 feb. 2017 a las 08:31