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

Mih*_*hta 30 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)
        }))
    }
}
Run Code Online (Sandbox Code Playgroud)

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

dea*_*eef 24

让我们从flatMap字典的定义开始,如下所示:

func flatMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
Run Code Online (Sandbox Code Playgroud)

你看到transform闭包只接受一个类型的参数,Element其中Element只是typealias一个元组:

public typealias Element = (key: Key, value: Value)
Run Code Online (Sandbox Code Playgroud)

所以闭包的第一个也是唯一的参数应该是两个元素(key类型Keyvalue类型Value)的元组.


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

try flatMap({ (key, value) in
    return try transform(key, value)
})
Run Code Online (Sandbox Code Playgroud)

你的闭包需要2个参数而不是1个(key类型Keyvalue类型Value).这在Swift 3中有效,这要归功于一个称为解构的功能,编译器会自动将2个元素的元组转换为2个参数.

但是,这个功能是怪异,很少使用,并给出意外的结果大部分时间,所以它在斯威夫特被删除4.
编辑:由于OOPer指出,这一功能已被暂时移除雨燕4测试版,但之前,必须重新添加最终版本已经发布.

相反,你应该写:

try flatMap({ tupleArgument in
    return try transform(tupleArgument.key, tupleArgument.value)
})
Run Code Online (Sandbox Code Playgroud)

你的flatMap功能变成:

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)
    }))
}
Run Code Online (Sandbox Code Playgroud)


OOP*_*Per 7

这是Swift 4提案的副作用:

SE-0110区分单元组和多元函数类型.

但是这个提案中包含的一些功能引起了一些回归,这篇文章在evolution-announce邮件列表的这篇文章中得到了解决:

[swift-evolution-announce] [核心团队]解决Swift 4中的SE-0110可用性回归问题

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

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)
    }))
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,在斯威夫特4,Dictionary具有采取一些新的初始化Sequence(Key, Value)对.例如:

init(uniqueKeysWithValues:S)


pka*_*amb 6

由于使用,我刚刚遇到了这个错误enumerated().map()

闭包元组参数不支持解构

我输入了代码:

["foo"].enumerated().map
Run Code Online (Sandbox Code Playgroud)

然后按Enter3 次,直到 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"
}
Run Code Online (Sandbox Code Playgroud)

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