关闭元组不支持Xcode 9 Swift 4中的解构

时间:2017-07-06 10:10:02

标签: ios swift swift4 xcode9-beta

在Xcode 9中的Swift 4光泽项目之后

我收到以下错误,我不知道

  

关闭元组参数'(key:_,value:_)'不支持   解构

代码:

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)
        }))
    }
}

此时出现错误try flatMap({ (key, value)in

4 个答案:

答案 0 :(得分:23)

让我们从以下字典的flatMap定义开始:

func flatMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]

您发现transform闭包仅采用类型为Element一个参数,其中Element只是元组的typealias:< / p>

public typealias Element = (key: Key, value: Value)

因此闭包的第一个且唯一的参数应该是两个元素的元组(类型为key的{​​{1}}和类型为{{1的Key }})。

现在,如果你查看你的代码(在Swift 3中编译),你会发现情况并非如此,你应该问为什么这甚至可以在Swift 3中运行。

value

您的闭包需要2个参数而不是Value类型try flatMap({ (key, value) in return try transform(key, value) }) key类型Key)。由于一个名为 destructuring 的功能,这在Swift 3中有效,编译器会自动将2个元素的元组转换为2个参数。

但是这个功能很奇怪,很少使用,并且大部分时间都会产生意想不到的结果,所以它已经在Swift 4中删除了。
修改:正如OOPer所指出的,此功能已在Swift 4测试版中暂时删除,但应在最终版本发布之前重新添加。

相反,你应该写:

value

您的Value功能变为:

try flatMap({ tupleArgument in
    return try transform(tupleArgument.key, tupleArgument.value)
})

答案 1 :(得分:6)

这是Swift 4提案的副作用:

SE-0110 Distinguish between single-tuple and multiple-argument function types

但此提案中包含的某些功能会导致一些回归,这在evolution-announce mailing list的帖子中得到解决:

[swift-evolution-announce] [Core team] Addressing the SE-0110 usability regression in Swift 4

因此,您可以预期在未来的Xcode 9的beta或GM版本中,您的代码将再次编译良好。在此之前,您可以使用这种解决方法:

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)
    }))
}

顺便说一句,在Swift 4中, document.addEventListener("backbutton", () => { console.log("[WARN] BackBtn pushed"); console.log("TextboxVal: " + this.inputValue); this.showConfirm(); document.removeEventListener("backbutton"); }); 有一些新的初始化程序,它们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) })) } DictionarySequence。例如:

init(uniqueKeysWithValues: S)

答案 2 :(得分:2)

由于使用enumerated().map(),我刚遇到此错误:

  

关闭元组参数不支持解构

我输入了密码:

["foo"].enumerated().map(

,然后持续按 Enter ,直到Xcode自动完成关闭样板为止。

自动完成功能似乎有一个导致上述错误的错误。自动完成功能会产生双括号((offset: Int, element: String)),而不是单括号(offset: Int, element: String)

我手动修复它,并能够继续:

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

可能是使用Xcode 10.0 beta(10L176w)的结果

答案 3 :(得分:0)

我正在使用Xcode 11.1和Swift 5,并在使用enumerated().map()时遇到此错误。我认为这个示例可以简化一些事情,但是总的来说,这就是解决该问题的方法。真正的错误是编译器无法推断出返回值:

// Correct Syntax
let resultModels: [ResultModel] = array.enumerated().map { index, model in
  // code
}

// Results in the error Closure tuple does not support destructuring
let resultModels = array.enumerated().map { index, model in
  // code
}