4

我正在尝试在 swift 3 中连接多个字符串:

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

编译时出现以下错误:

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

这曾经在 swift 2 中工作。我不知道为什么它不再工作了。

4

5 回答 5

8

OP 提交的错误报告:

已解决(2017 年 1 月 3 日提交给 master 的修复),因此在即将推出的 Swift 3.1 中应该不再是问题。


这似乎是与以下情况相关的错误(Swift 2.2 中不存在,仅 3.0 中):

  • 对表达式中的至少 3 个项使用强制展开运算符 ( !)(使用至少 2 个基本运算符进行测试,例如+-)。
  • 出于某种原因,鉴于上述情况,Swift 搞砸了表达式的类型推断(特别是对于x!术语本身,在表达式中)。

对于以下所有示例,让:

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

存在的错误:

// 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

错误不存在:

/* 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!)

但是,由于这是 Swift 3.0- dev,我不确定这是否真的是一个“错误”,以及在尚未生产的代码版本中报告“错误”的政策是什么,但可能你应该提交雷达为此,以防万一。

至于回答你的问题是如何规避这个问题:

  • 使用例如中间变量,如Bug 不存在:上面的示例 2
  • 或者明确告诉 Swift 3-term 表达式中的所有术语都是字符串,如Bug not present: Example 3 above,
  • 或者,更好的是,使用可选绑定的安全展开,例如使用可选绑定

    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   */
    
于 2016-03-30T19:50:26.603 回答
2

斯威夫特 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!
于 2017-06-01T07:09:31.810 回答
1
func getSingleValue(_ value: String?..., seperator: String = " ") -> String? {

    return value.reduce("") {
        ($0) + seperator + ($1 ?? "")
        }.trimmingCharacters(in: CharacterSet(charactersIn: seperator) )
}
于 2018-05-05T14:12:42.930 回答
0
let val: String? = "nil"

val.flatMap({(str: String) -> String? in
    return str + "value"
})
于 2017-02-15T09:31:16.977 回答
0
var a:String? = "a"
var b:String? = "b"
var c:String? = "c"
var d:String? = ""

let arr = [a,b,c]
arr.compactMap { $0 }.joined(separator: " ")

compactMap 用于从扁平数组中过滤掉 nil 值

于 2019-02-19T12:11:35.350 回答