Swift:对成员的引用不明确';地图';

Swift:对成员的引用不明确';地图';,swift,Swift,我正在读“swift编程语言4.2”。在第23页的第一章中,我有以下要求: 重写闭包,使所有奇数返回零 我的解决方案是: let myArray: [Int] = [1, 2, 3, 4, 5] myArray.map({ (number: Int) in if number % 2 != 0 { return 0 } else { return number } }) 但我有以下错误: 对成员“映射”的引用不明确 我真的不明白为什么我错了,为

我正在读“swift编程语言4.2”。在第23页的第一章中,我有以下要求:

重写闭包,使所有奇数返回零

我的解决方案是:

let myArray: [Int] = [1, 2, 3, 4, 5]

myArray.map({ (number: Int) in 
   if number % 2 != 0 {
       return 0
   } else {
       return number
   }
})
但我有以下错误:

对成员“映射”的引用不明确

我真的不明白为什么我错了,为什么我的“myArray”不能引用“map”成员? 你能给我解释一下这个错误和正确的解决方法吗?
谢谢大家!

通过使用
将返回类型指定为[Int]
来减少歧义:

myArray.map({ (number: Int) in 
   if number % 2 != 0 {
       return 0
   } else {
       return number
   }
}) as [Int]
或:

正如瓦迪安(vadian)所指出的那样:这种歧义来自于无法推断闭包中的泛型返回类型这一事实

为了理解编译器如何推断闭包的返回类型,让我们回到闭包的语法:

let myClosure: returnType = { (params) -> returnType in
    statements
}
这里,
myClosure
的类型是
returnType
。它设置在两个位置:在
之后和
->
之后。您可以通过从两个位置之一删除
returnType
来使用类型推断,但不能同时从两个位置删除

因此,您可以将其从花括号中移除(如上面的代码所示):

或者紧跟在变量名之后,并在花括号内指定闭包的返回类型:

let result = myArray.map({ (number: Int) -> Int in

您必须指定闭包的返回类型,而不是注释参数类型

let myArray = [1, 2, 3, 4, 5] // You don't even need to annotate the array, the compiler knows the type.

let result = myArray.map({ number -> Int in
    if number % 2 != 0 {
        return 0
    } else {
        return number
    }
})
或者使用尾随闭包语法和速记参数名称。在这种情况下,编译器可以推断出一切

let result = myArray.map { $0 % 2 != 0 ? 0 : $0 }

与您的问题无关,但闭包的返回类型在哪里?对于奇数返回0的逻辑是错误的。对于偶数,您返回0。哦,对不起:D我现在不关注真正的逻辑。我会编辑的,谢谢!当然,但如果没有返回类型,则不会返回任何内容。另外,你的代码对我来说编译得很好,返回类型是。你能发布一个带有错误的playrground的屏幕截图吗?(最好是完整的游乐场)基本上是一个副本:您必须提供返回类型您将号码返回到哪里?我在任何地方都看不到退货类型。非常感谢。不幸的是,由于新的成员策略,我无法对您的答案进行投票:(@yesterdayoncemore很高兴我能提供帮助这不是一个bug。如果您指定完整闭包,您还必须指定闭包的(静态)返回类型(如我的回答中所示)或者对函数的返回类型进行注释,如第二个示例中所示。在后一种情况下,编译器会根据注释推断闭包返回类型。@yesterdayoncemore可能会有所帮助谢谢您的帮助!我可以得到另一个很好的解决方案!:)自动推断与尾部闭包语法或速记参数名称无关,
myArray.map({number in number%2!=0?0:number})
也会编译。对于单表达式闭包,返回类型是自动推断的,比较(我很想把这个问题作为一个重复来结束)。
let myArray = [1, 2, 3, 4, 5] // You don't even need to annotate the array, the compiler knows the type.

let result = myArray.map({ number -> Int in
    if number % 2 != 0 {
        return 0
    } else {
        return number
    }
})
let result = myArray.map { $0 % 2 != 0 ? 0 : $0 }