【问题标题】:Unable to return a filtered array无法返回过滤后的数组
【发布时间】:2016-03-15 20:55:36
【问题描述】:

概述

我是 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)'
错误子文本: Expected an argument list of type '(@noescape (Self.Generator.Element) throws -> Bool)'

来源:Sample MCVEExecute 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 MCVEExecute 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 MCVE (Execute here)

其他信息

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

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

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

如果有人能够解释为什么会发生这种情况,并给出一个明确的判断,因为编译器错误消息并没有尽可能的有用,那么我对错误消息的阅读/解释并不像它可能的那样清楚一直,可能通过以某种方式改变我的心态来节省时间,或者,请评论该注释。

Victor Sigler's answer 似乎确实详细介绍了这一点。

【问题讨论】:

  • 看起来func someFunc(var1: String) { 没有明确的返回类型,因此推断返回类型为()Void/空元组)。在这种情况下,尝试在字典数组上返回 filter 操作的结果是没有意义的,因为这将是字典本身的数组(可能为空)。考虑向我们展示一个 minimal, complete and verifiable 示例,而不是单独使用几个 sn-ps。
  • @Pysis 查看我的回答以澄清您的疑问
  • @dfri 这个评论更能代表一个答案,我已经把我的想法粘贴在我自己的里面了。对于 MCVE,我特意展示了“声明”和“各种试验”部分,以便将它们配对在一起以创建示例 MCVE,并展示我尝试过的不同语法组合,还展示了哪些代码直接导致了各种错误消息。
  • 如果有人还需要查看更多“完整”代码示例,我已经添加了一些链接。
  • @Pysis 我不会在这里贬低您的努力,但是对于真正的 MVCE(这使得我们可能的回答者尽可能容易地帮助您),以我们可以直接使用它来重现您的问题,而无需将部分修补在一起。您上面的编辑现在确实包含指向此类示例的链接,但考虑下次仅从 MVCE 开始(未链接到,但粘贴在代码块中)。此后,如果适用,请自行包括详细信息和调查。 ...

标签: arrays swift dictionary higher-order-functions


【解决方案1】:

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

第 1 组:

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

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

关于@noescape

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

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

所以要恢复它,如果您将功能更改为以下内容,它应该可以工作:

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

第 2 组:

如果您修复了 Set 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
   })
}

希望对你有所帮助。

【讨论】:

  • 这个答案确实提供了有关错误消息和解决方案的一些详细信息,也适用于每个集合,尽管我只提供每个作为示例来显示编译器显示的不同解析错误消息,以试图更好地理解一个问题。我邀请人们回答我的答案只是为了强调有关调试技​​术和编译器似乎具有的潜在关系的附加信息。
  • @Pysis 我的回答解决了你的问题,我很抱歉这么说但是stackoverflow 不是一个辩论论坛,事实上如果你的问题太宽泛可以关闭。如果我的问题解决了您的问题,请接受它对其他人有帮助。
  • 啊,是的,我只是想澄清一下,我认为您的回答涵盖了某些领域,而我的回答涵盖了其他一些领域。
猜你喜欢
  • 2017-10-07
  • 2021-10-02
  • 2019-01-22
  • 2022-11-25
  • 2020-09-24
  • 1970-01-01
  • 1970-01-01
  • 2019-12-09
相关资源
最近更新 更多