【问题标题】:Swift: Ambiguous reference to member 'map'斯威夫特:对成员“地图”的模糊引用
【发布时间】:2018-09-01 17:47:42
【问题描述】:

我正在阅读“快速编程语言 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' 成员? 你能给我解释一下这个错误以及正确的解决方案吗? 谢谢!

【问题讨论】:

  • 与你的问题无关,但是闭包的返回类型在哪里呢?你为奇数返回 0 的逻辑是错误的。偶数返回 0。
  • 哦抱歉 :D 我现在不关注真正的逻辑。我会编辑的,谢谢!
  • 当然,但如果您没有返回类型,则不会返回任何内容。您的代码也可以通过返回类型编译得很好。
  • 您能否发布您的游乐场的屏幕截图并显示错误? (最好是完整的游乐场)
  • 基本上是stackoverflow.com/questions/34113457/…的副本:你必须提供闭包返回类型

标签: swift


【解决方案1】:

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

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

或者:

let result: [Int] = myArray.map({ (number: Int) in
    if number % 2 != 0 {
        return 0
    } else {
        return number
    }
})
print(result) //[0, 2, 0, 4, 0]

正如 vadian 所述:歧义来自于闭包中的通用返回类型无法推断的事实。

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

let myClosure: returnType = { (params) -> returnType in
    statements
}

这里,myClosure 的类型是returnType。它设置在两个地方:: 之后和-> 之后。您可以通过从两个位置之一删除returnType 来使用类型推断,但不能同时删除。

所以你可以从花括号里面删除它(就像上面的代码):

let result: [Int] = myArray.map({ (number: Int) in

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

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

【讨论】:

  • 您将号码返回到哪里?我在任何地方都看不到返回类型。
  • 非常感谢。不幸的是,由于新的会员政策,我不能赞成你的回答:(
  • @yesterdayoncemore 很高兴我能帮上忙
  • 这不是错误。如果您指定完整的闭包,您还必须指定 closure 的(静态)返回类型(如我的回答)或注释 function 的返回类型,如在你的第二个例子中。在后一种情况下,编译器从注解中推断出闭包返回类型。
  • @yesterdayoncemore This 可能会有所帮助
【解决方案2】:

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

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 }

【讨论】:

  • 感谢您的帮助!我可以拥有的另一个不错的解决方案! :)
  • “自动推理”与尾随闭包语法或速记参数名称无关,myArray.map({ number in number % 2 != 0 ? 0 : number }) 也可以编译。对于单个表达式闭包,返回类型是自动推断的,比较stackoverflow.com/a/34115788/1187415(我很想把这个问题作为重复来结束)。
猜你喜欢
  • 1970-01-01
  • 2017-07-22
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
相关资源
最近更新 更多