无法 return 过滤数组

Unable to return a filtered array

概览

我是 Swift 语言的新手,而不是其他语言,并且在执行一个简单的 Array.filter 语句时遇到问题,我想 return 作为函数的结果在我正在写的 class 中,但似乎添加 return 关键字会导致非直观的编译错误。

问题:有谁知道这些错误消息是怎么回事,以及如何解决它们?

示例

声明

var arrDictIVar = [["dictVar1": "value"]]
...
func someFunc(var1: String) {...

各种试炼

设置 1

return arrDictIVar.filter({
  [=12=]["dictVar1"] == var1
}) 

return arrDictIVar.filter(){
  [=12=]["dictVar1"] == var1
}

return arrDictIVar.filter{
  [=12=]["dictVar1"] == var1
}

错误: Cannot invoke 'filter' with an argument list of type '(@noescape ([String : String]) throws -> Bool)'
错误子文本: Expected an argument list of type '(@noescape (Self.Generator.Element) throws -> Bool)'

来源:Sample MCVE Execute here

设置 2

return arrDictIVar.filter({
  [=13=]["dictVar1"] == var1
})[0]

return arrDictIVar.filter() {
  [=13=]["dictVar1"] == var1
}[0]

return arrDictIVar.filter{
  [=13=]["dictVar1"] == var1
}[0]

错误: Cannot subscript a value of type '[[String : String]]'

来源:Sample MCVE Execute here

第 3 组

arrDictIVar.filter({
   [=14=]["dictVar1"] == var1
})

arrDictIVar.filter(){
   [=14=]["dictVar1"] == var1
}

arrDictIVar.filter{
   [=14=]["dictVar1"] == var1
}

警告: Result of call to 'filter' is unused 注意: 只是为了表明没有 return 关键字的块是正确形成的。

来源:Sample MCVE (Execute here)

其他信息

我也曾多次尝试将 IVar 声明修改为 var arrDictIVar: Array<Dictionary<String,String>> = [...,并将函数声明修改为 func someFunc(var1: String) -> Dictionary<String,String>{...,但都出现了类似的失败。

编辑: 我在提出这个问题的同时发布了 an answer,因为我发现了一个组合,该组合在这篇文章即将结束时起作用。它确实包括更改方法签名中的 return 数据类型,以及提供暗示编译器不准确或至少令人困惑的性质的其他信息,以及它显示的错误消息。

在此之后我留下了一个后续问题:

If anyone would be able to explain why this was happening, and give a clear judgement as the compiler error message was not as helpful as it could be, my reading/interpretation of the error message was not as clear as it could have been, potentially saving time by changing my mindset somehow, or either, please comment on that note.

似乎很详细地介绍了这一点。

让我们详细解释一下您在问题中提出的每一组:

Set 1:

你的三个例子在代码中是正确的,对编译器来说是一样的,你使用的是尾随闭包,括号可以省略。

有时编译器(因为它还很年轻!!!)无法准确显示代码中发生的错误,但在这一步中您肯定会使用 filter 函数来 return [[String: String]] 或字典数组,并且您缺少函数的 return 类型,编译器将其假定为 Void

关于@noescape:

添加@noescape 保证闭包不会存储在某处、稍后使用或异步使用。请记住,闭包捕获值。

您可以在以下两个非常好的教程中阅读有关 @noescape 子句的更多信息:

所以要恢复它,如果您将函数更改为以下它应该可以工作:

func someFunc(var1: String) -> [[String: String]] {
   return arrDictIVar.filter({
      [=10=]["dictVar1"] == var1
   })
}

Set 2:

如果您修复了 组 1 中的错误,那么当您编码时:

return arrDictIVar.filter{
   [=11=]["dictVar1"] == var1
}[0]

您正在尝试 return 一个 [String: String] 或一个字典,但关于函数的 return 类型是错误的 [[String: String]]

但要小心,因为如果将 return 类型更改为 [String: String] 并尝试为 filter 函数索引数组 returned 并且没有任何依据通过 filter 函数你会得到一个运行时错误。

Set 3

我认为它更容易理解,因为正如警告所说,filter 函数 return 是一个新的元素列表,如果您不保存它或 returned 在你的函数中它是未使用的,像这样:

func someFunc(var1: String){
   arrDictIVar.filter({
      [=12=]["dictVar1"] == var1
   })
}

希望对你有所帮助。