无法返回已过滤的数组

时间:2016-03-15 20:55:37

标签: arrays swift dictionary higher-order-functions

概述

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

问题:有谁知道如何处理这些错误消息,以及如何修复它们?

样品

声明

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

各种试验

设置1

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

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

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

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

来源:Sample MCVE Execute here

设置2

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

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

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

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

来源:Sample MCVE Execute here

设置3

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

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

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

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

来源:Sample MCVEExecute here

其他信息

我还尝试将IVar声明修改为var arrDictIVar: Array<Dictionary<String,String>> = [...,并在不同时间将函数声明修改为func someFunc(var1: String) -> Dictionary<String,String>{...,并发生类似的失败。

编辑:我在此问题的同时发布了an answer,因为我发现了一个可以接近发布结尾的组合。它确实包括更改方法签名中的返回数据类型,以及提供其他信息,暗示编译器的不准确或至少令人困惑的性质,以及它所呈现的错误消息。

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

  

如果有人能够解释为什么会发生这种情况,并且由于编译器错误消息没有那么有用而给出明确的判断,那么我对错误消息的读取/解释并不像它可能有的那么清楚曾经,可能通过某种方式改变我的心态来节省时间,或者或者,请对该说明发表评论。

Victor Sigler's answer似乎确实涵盖了一些细节。

1 个答案:

答案 0 :(得分:1)

让我们详细解释你在问题中提出的每一套:

  

设置1:

您的三个示例在代码中是正确的,并且与编译器相同,您使用的是尾随闭包,并且可以省略括号。

有时编译器(因为它太年轻了!!!)没有显示代码中发生的确切错误,但是在这一步中你肯定使用filter函数返回[[String: String]]或者是一个字典数组,你错过了函数返回的类型,它被编译器假定为Void

关于@noescape

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

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

所以要恢复它,如果你将你的功能改为以下它应该有效:

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

设置2:

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

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

您正在尝试返回[String: String]或字典,而且函数的返回类型为[[String: String]]是错误的。

但要小心,因为如果将返回类型更改为[String: String]并尝试索引为filter函数返回的数组,那么filter函数就没有任何内容运行时错误。

  

设置3

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

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

我希望这对你有所帮助。