Ios 在Xcode 9 Swift 4中,闭包元组不支持解构

Ios 在Xcode 9 Swift 4中,闭包元组不支持解构,ios,swift,swift4,xcode9-beta,Ios,Swift,Swift4,Xcode9 Beta,在Xcode 9中Swift 4的光泽项目之后 我得到以下错误,我不知道 闭包元组参数“(键:\值:\)”不支持 解构 代码: extension Dictionary { init(elements: [Element]) { self.init() for (key, value) in elements { self[key] = value } } func flatMap<KeyPr

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

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

闭包元组参数“(键:\值:\)”不支持 解构

代码:

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)
        }))
    }
}
扩展字典
{
初始化(元素:[元素]){
self.init()
对于元素中的(键、值){
自[键]=值
}
}
func平面映射(u变换:(键,值)抛出->(键素数,值素数)?)返回->[键素数:值素数]{
返回字典(元素:在
返回try转换(键、值)
}))
}
}

此时出现错误
请尝试
中的flatMap({(键,值)

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

func flatMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
您可以看到,
转换
闭包只接受类型为
元素
一个参数,其中
元素
只是元组的
类型别名

public typealias Element = (key: Key, value: Value)
因此闭包的第一个也是唯一的参数应该是两个元素的元组(
key
类型
key
value
类型
value


现在,如果你看一下你的代码(在Swift 3中编译),你会发现情况并非如此,你应该问为什么这在Swift 3中仍然有效

try flatMap({ (key, value) in
    return try transform(key, value)
})
闭包采用两个参数,而不是一个(
key
类型的
key
value
类型的
value
)。这在Swift 3中起作用,这得益于一个名为destructuring的功能,编译器将自动将两个元素的元组转换为两个参数

但是这个功能很奇怪,很少使用,而且大多数时候都会产生意想不到的结果,所以它在Swift 4中被删除了。
编辑:正如OOPer所指出的,此功能已在Swift 4 beta版中暂时删除,但应在最终版本发布前重新添加

相反,你应该写:

try flatMap({ tupleArgument in
    return try transform(tupleArgument.key, tupleArgument.value)
})
然后您的
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)
    }))
}
func平面映射(u变换:(键,值)抛出->(键素,值素)?)返回->[键素:值素]{
返回字典(元素:try flatMap({element in
返回try转换(element.key、element.value)
}))
}

这是Swift 4提案的一个副作用:

但该提案中包含的一些特征导致了一些回归,这在以下的帖子中得到了阐述:

因此,您可以预期,在未来的Xcode 9测试版或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)
    }))
}
internal func flatMap(u-transform:(Key,Value)抛出->(KeyPrime,ValuePrime)?)返回->[KeyPrime:ValuePrime]{
返回字典(元素:try flatMap({pair in
let(键,值)=对
返回try转换(键、值)
}))
}

顺便说一下,在Swift 4中,
字典
有一些新的初始值设定项,它们采用
序列
(键、值)
对。例如:


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

闭包元组参数不支持分解结构

我输入了密码:

["foo"].enumerated().map
然后按Enter键3次,直到Xcode自动完成闭包样板

自动完成似乎有一个导致上述错误的错误。自动完成生成双括号
((偏移量:Int,元素:String))
,而不是单括号
(偏移量:Int,元素: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)的结果。

我使用的是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
}

Dictionary.init(元素:)在Swift标准库中找不到< /代码>。您自己定义它吗?是的,我正在更新回答。我已经解释了解释的答案。它是第三方库,我想与SWIFT4兼容。我确认这一点,但是修复并不能解决所有问题。请考虑这一点:<代码>让ALLROLALISS([(字符串,字符串)] ]=Locale.isoRegionCodes.map({($0,Locale.current.localizedString(forRegionCode:$0)?“未知”)}).排序的{((c0:String,r0:String),(c1:String,r1:String))->返回的Bool r0
有什么问题
选项人们可能会想知道。假设我想省略
c1,c2
,将它们替换为` `。看不出有什么办法可以做到。@PaulB这至少对错误闭包元组参数来说是有意义的,它不支持解构。意思是你(目前)不能使用解构元组作为闭包的参数。希望将来会添加到该语言中。切换到结构化元组参数,它就可以正常工作:
.sorted{(locale0,locale1)->Bool in
。我的代码示例中的参数不是元组,但Xcode autocomplete已经通过额外的
()
。是的,@pkamb,就是这种情况。可以随意使用参数标签,但由于相应的错误消息状态,不支持“就地”分解元组。因此,令人惊讶的是,在某些情况下,您实际上可以以某种方式分解元组(或元组?),并编写如下内容:
let pass=[“foo”].enumerated().map{(offset:Int,ux:String)->返回的字符串“works”}