【问题标题】:How to use an array of functions in Swift如何在 Swift 中使用函数数组
【发布时间】:2020-09-03 22:20:16
【问题描述】:

我已经阅读了我可以在这里找到的所有关于函数数组的帖子——你可以做到这一点。我估计。但是没有一篇文章实际上展示了如何使用它们(至少不是我想要做的)。这就是我想要的 - 它们都可以采用相同的参数,但这不是必需的。

这篇文章结束了,我可以循环执行每个函数(满足第一个目标)。
https://stackoverflow.com/a/24447484/11114752

但是...如果我想通过引用执行单个函数怎么办? 换句话说,如何只调用引用的 Arity2 函数 - 例如:

// None of these work (with or without the parameter labels)
funcs.Arity2(n: 2, S: "Fred)    // value of type [MyFuncs] has no member .Arity2
funcs[Arity2](n: 2, S: "Fred")  // no exact matches to call in subscript
funcs[.Arity2](n: 2, S: "Fred") // Cannot call value of non-function type...

let fn = funcs.first(where: { a whole ton of permutations here to try to match Arity2 }) -- a whole lotta frustrating nope...

请帮忙!我尝试过的没有任何效果。预编译器只是兜圈子,提出不成功且无法编译的建议。

编辑: 首先是数组的原因是我将有相当多的功能,并且我不知道它们都是什么提前。本质上,我想要一种插件类型的架构。我可以添加到函数列表中(最好是在类的扩展中,但这是另一个问题..),而不是更改按顺序执行每个函数的处理循环。

【问题讨论】:

  • 您所遵循的答案没有必要复杂(除非您正在做的事情比您描述的要复杂得多)。检查以下对同一问题的答案(该页面上的许多答案都与 1.0 之前的 Swift 相关):stackoverflow.com/a/26416417/97337 写下您尝试调用的几个函数的示例。 没有数组你会怎么做呢?只需对它们进行硬编码并显示您想要调用的内容,我们将展示如何将其转换为数组。
  • 我尝试了 pawello2222 的回答 - 它不能与函数一起正常工作,这让我很沮丧。
  • @Rob - 这是我的替代方案,也是我现在正在使用的。第一个目标 - 执行所有函数(按数组顺序 - 第一个函数第一个,第二个,...)。第二个目标 - 按名称单独访问。所以,看起来我需要两个数组,除非命名的数组还保持它们声明的顺序(需要一些测试)。
  • 测试确认订单似乎按预期维持

标签: arrays swift function


【解决方案1】:

我假设你需要类似的东西

    _ = funcs.first {
        if case let MyFuncs.Arity2(f) = $0 {
            f(2, "Fred")
            return true
        }
        return false
    }

【讨论】:

  • 是的!这就是我一直在寻找的魔法咒语——结合 if、case 和 .first。哇 - 必须爱斯威夫特:)。鉴于复杂性和我必须处理条件的事实,我正在重新考虑我的方法 - 但这回答了问题 - 谢谢。
  • 重新检查:即使我只知道名字,这似乎也有效
【解决方案2】:

如果你知道函数在数组中的位置,就可以更简单地实现。

假设你有:

func someFunc(n: Int, s: String) { 
    print("call \(n) \(s)")
}

var funcs = [MyFuncs.Arity2(someFunc)]

你可以这样做:

if case .Arity2(let f) = funcs.first {
    f(2, "Fred")
}

通过将funcs.first 替换为funcs[i],您可以访问i-th 索引(首先确保它确实存在)。

【讨论】:

  • 我喜欢这个。它毫无怨言地编译。但是,我确认,在 init() 中,我有: funcs.append(MyFuncs.Arity2(someFunc)) 还确认 funcs 在调试器中包含 Arity2。但是 if 语句永远不会触发(使用 .first 或 [0])
  • @MichaelStone 我假设你知道你的函数在数组中的位置。
  • code var lFn = Array()。 ... init(){ lFn.append(MyFuncs.Arity2(someFunc)) }。 ...建议如果上面的块从不执行该功能。但是,如果这样做的话,那就太好了!我知道名称 (Arity2) 和位置 (0),但 funcs.first 和 funcs[0] 似乎都不满足条件。虽然我可能不知道我实际使用中的位置。我错了,位置是 1,这确实有效。所以,如果我只知道名字,我仍然需要 .first(where; ...)。
  • @MichaelStone 是的,它只有在你知道职位的情况下才有效。否则,您需要按照 Asperi 的建议搜索第一个匹配的签名。
  • 是的,再一次 - 除非我遗漏了什么,否则它似乎只有在我指定正确的位置时才有效(例如:如果 Arity2 真的是第一个元素,或者如果我在括号中指定了正确的位置)。我现在将示例中的 Arity0 作为第一个元素,将 Arity2 作为第二个元素,以确保我正在测试正确的场景。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
相关资源
最近更新 更多