ios - color - La tupla de cierre no admite la desestructuración en Xcode 9 Swift 4
menu ios (3)
Acabo de encontrar este error como resultado del uso de enumerated().map()
:
El parámetro de tupla de cierre no admite la desestructuración
Escribí el código:
["foo"].enumerated().map(
Y luego siguió presionando Intro hasta que Xcode completó automáticamente la placa de cierre.
El autocompletar aparentemente tiene un error que causa el error anterior. El autocompletado produce paréntesis doble ((offset: Int, element: String))
lugar de paréntesis simple (offset: Int, element: String)
.
Lo arreglé manualmente y pude continuar:
// Xcode autocomplete suggests:
let fail = ["foo"].enumerated().map { ((offset: Int, element: String)) -> String in
return "ERROR: Closure tuple parameter does not support destructuring"
}
// Works if you manually replace the "(( _ ))" with "( _ )"
let pass = ["foo"].enumerated().map { (offset: Int, element: String) -> String in
return "works"
}
Posiblemente el resultado de usar Xcode 10.0 beta (10L176w)
Después del proyecto de brillo para Swift 4 en Xcode 9
Estoy recibiendo error siguiente que no tengo idea
El parámetro de tupla de cierre ''(clave: _, valor: _)'' no admite la desestructuración
Código:
extension Dictionary
{
init(elements: [Element]) {
self.init()
for (key, value) in elements {
self[key] = value
}
}
func flatMap<KeyPrime, ValuePrime>(_ transform: (Key, Value) throws -> (KeyPrime, ValuePrime)?) rethrows -> [KeyPrime:ValuePrime] {
return Dictionary<KeyPrime, ValuePrime>(elements: try flatMap({ (key, value) in
return try transform(key, value)
}))
}
}
El error llega en este punto, try flatMap({ (key, value)in
Comencemos con la definición de flatMap
para un diccionario que es el siguiente:
func flatMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
Verá que el cierre de transform
toma solo un parámetro de tipo Element
donde Element
es solo una typealias
de una tupla:
public typealias Element = (key: Key, value: Value)
Entonces, el primer y único argumento del cierre debe ser una tupla de dos elementos ( key
de tipo Key
y value
de tipo Value
).
Ahora, si observa su código (que se compila en Swift 3), verá que este no es el caso, y debería preguntarse por qué funciona esto en Swift 3.
try flatMap({ (key, value) in
return try transform(key, value)
})
Su cierre toma 2 argumentos en lugar de uno ( key
de tipo Key
y value
de tipo Value
). Esto funciona en Swift 3 gracias a una característica llamada desestructuración donde el compilador transformará automáticamente una tupla de 2 elementos en 2 argumentos.
Pero esta característica es rara, rara vez se usa y da resultados inesperados la mayor parte del tiempo por lo que se ha eliminado en Swift 4.
Edición : Como lo señaló OOPer, esta función se ha eliminado temporalmente en Swift 4 beta, pero debe volver a agregarse antes de que salga la versión final.
En su lugar deberías estar escribiendo:
try flatMap({ tupleArgument in
return try transform(tupleArgument.key, tupleArgument.value)
})
Y tu función flatMap
convierte en:
func flatMap<KeyPrime, ValuePrime>(_ transform: (Key, Value) throws -> (KeyPrime, ValuePrime)?) rethrows -> [KeyPrime:ValuePrime] {
return Dictionary<KeyPrime, ValuePrime>(elements: try flatMap({ element in
return try transform(element.key, element.value)
}))
}
Es un efecto secundario de esta propuesta para Swift 4:
SE-0110 Distinguir entre tipos de función de tupla simple y argumento múltiple .
Pero algunas de las características incluidas en esta propuesta causaron cierta regresión que se aborda en esta publicación de la lista de correo de evolución-anuncio :
[anuncio-evolución-rápida] [equipo central] Aborda la regresión de usabilidad SE-0110 en Swift 4
Por lo tanto, puede esperar que en la futura versión beta o GM de Xcode 9, su código se compile nuevamente. Hasta entonces, puede utilizar este tipo de solución:
internal func flatMap<KeyPrime , ValuePrime>(_ transform: (Key, Value) throws -> (KeyPrime, ValuePrime)?) rethrows -> [KeyPrime : ValuePrime] {
return Dictionary<KeyPrime,ValuePrime>(elements: try flatMap({ pair in
let (key, value) = pair
return try transform(key, value)
}))
}
Por cierto, en Swift 4, Dictionary
tiene algunos inicializadores nuevos que toman el par de Sequence
de (Key, Value)
. Por ejemplo: