¿Cómo puedo concatenar múltiples cadenas opcionales en swift 3.0?

Estoy tratando de concatenar múltiples cadenas en Swift 3:

var a:String? = "a" var b:String? = "b" var c:String? = "c" var d:String? = a! + b! + c! 

Al comstackr recibo el siguiente error:

 error: cannot convert value of type 'String' to specified type 'String?' var d:String? = a! + b! + c! ~~~~~~~~^~~~ 

Esto solía funcionar en swift 2. No estoy seguro de por qué ya no funciona.

Informe de error presentado por OP:

  • SR-1122: Error al tipear la cadena de operadores binarios en valores sin fuerza forzada

Lo cual se ha resuelto (corregido comprometido a dominar el 3 de enero de 2017) y, por lo tanto, ya no será un problema en el próximo Swift 3.1.


Esto parece ser un error (no presente en Swift 2.2, solo 3.0) asociado con el caso de:

  • Usar el operador de desenvolvimiento forzado ( ! ) Durante al menos 3 términos en una expresión (probado usando al menos 2 operadores básicos, p. Ej., + O - ).
  • Por alguna razón, dado lo anterior, Swift arruina la inferencia tipo de la expresión (específicamente, para los términos x! sí mismos, en la expresión).

Para todos los ejemplos a continuación, deja:

 let a: String? = "a" let b: String? = "b" let c: String? = "c" 

Bug presente

 // example 1 a! + b! + c! /* error: ambiguous reference to member '+' */ // example 2 var d: String = a! + b! + c! /* error: ambiguous reference to member '+' */ // example 3 var d: String? = a! + b! + c! /* error: cannot convert value of type 'String' to specified type 'String?' */ // example 4 var d: String? d = a! + b! + c! /* error: cannot assign value of type 'String' to specified type 'String?' */ // example 5 (not just for type String and '+' operator) let a: Int? = 1 let b: Int? = 2 let c: Int? = 3 var d: Int? = a! + b! + c! /* error: cannot convert value of type 'Int' to specified type 'Int?' */ var e: Int? = a! - b! - c! // same error 

Error no presente:

 /* example 1 */ var d: String? = a! + b! /* example 2 */ let aa = a! let bb = b! let cc = c! var d: String? = aa + bb + cc var e: String = aa + bb + cc /* example 3 */ var d: String? = String(a!) + String(b!) + String(c!) 

Sin embargo, como esto es Swift 3.0- dev , no estoy seguro de si esto es realmente un “error”, y cuál es la política wrt que informa “errores” en una versión de código aún no producida, pero posiblemente debería archivar el radar para esto, solo por si acaso.

En cuanto a responder a su pregunta sobre cómo eludir este problema:

  • use, por ejemplo, variables intermedias como en Bug no presente: Ejemplo 2 anterior,
  • o explícitamente decirle a Swift que todos los términos en la expresión de 3 términos son cadenas, como en el error no presente: Ejemplo 3 anterior,
  • o, mejor aún, utilice un desenvolvimiento seguro de su opción, por ejemplo, utilizando un enlace opcional :

     var d: String? = nil if let a = a, b = b, c = c { d = a + b + c } /* if any of a, b or c are 'nil', d will remain as 'nil'; otherwise, the concenation of their unwrapped values */ 

Swift 3

 let q: String? = "Hello" let w: String? = "World" let r: String? = "!" var array = [q, w, r] print(array.flatMap { $0 }.reduce("", {$0 + $1})) // HelloWorld! let q: String? = "Hello" let w: String? = nil let r: String? = "!" var array = [q, w, r] print(array.flatMap { $0 }.reduce("", {$0 + $1})) // Hello! 
 let val: String? = "nil" val.flatMap({(str: String) -> String? in return str + "value" }) 
 func getSingleValue(_ value: String?..., seperator: String = " ") -> String? { return value.reduce("") { ($0) + seperator + ($1 ?? "") }.trimmingCharacters(in: CharacterSet(charactersIn: seperator) ) }