Estoy tratando de asignar un valor a x desde una función f que toma un parámetro (una cadena) y lo lanza.
El alcance actual arroja, así que creo que no se requiere un do ... catch .
¿Estoy tratando de usar try con el operador coalescente ?? pero recibo este error: 'try' cannot appear to the right of a non-assignment operator .
guard let x = try f("a") ?? try f("b") ?? try f("c") else { print("Couldn't get a valid value for x") return } Si cambio try de try? :
guard let x = try? f("a") ?? try? f("b") ?? try? f("c") else { print("Couldn't get a valid value for x") return } Recibo la advertencia Left side of nil coalescing operator '??' has non-optional type 'String??', so the right side is never used y el error: 'try?' cannot appear to the right of a non-assignment operator .
Si pongo cada intento? entre paréntesis:
guard let x = (try? f("a")) ?? (try? f("b")) ?? (try? f("c")) else { print("Couldn't get a valid value for x") return }Se compila, pero x es opcional y me gustaría que se desenvolviera.
si quito los signos de interrogación:
guard let x = (try f("a")) ?? (try f("b")) ?? (try f("c")) else { print("Couldn't get a valid value for x") return } Recibo el error El Operator can throw but expression is not marked with 'try' .
Estoy usando Swift 4.2 (lo último en Xcode al momento de escribir).
¿Cuál es la forma correcta de hacer esto para obtener un valor sin envolver en x ?
Actualización: * El tipo de retorno de f() es String?. Creo que el hecho de que sea una cadena opcional es importante.
Un solo try puede cubrir toda la expresión, por lo que solo puede decir:
guard let x = try f("a") ?? f("b") ?? f("c") else { print("Couldn't get a valid value for x") return } Lo mismo ocurre con try? :
guard let x = try? f("a") ?? f("b") ?? f("c") else { print("Couldn't get a valid value for x") return } Aunque tenga en cuenta que en Swift 4.2 x será String? debido al hecho de que usted está aplicando try? a un valor que ya es opcional, lo que le brinda una opción doblemente envuelta de la que guard let Let solo desenvolverá una capa.
Para remediar esto, podría coalescer a nil :
guard let x = (try? f("a") ?? f("b") ?? f("c")) ?? nil else { print("Couldn't get a valid value for x") return } Pero en Swift 5 esto es innecesario debido a SE-0230 , ¿dónde try? f("a") ?? f("b") ?? f("c") se aplanará en un solo valor opcional automáticamente por el compilador.