【问题标题】:Swift Generic Type in Function + Higher Order Function函数中的 Swift 泛型类型 + 高阶函数
【发布时间】:2018-02-08 09:50:27
【问题描述】:

假设我有一个通用方法来进行一些转换,它需要输入和输出,部分流程需要一个块(也需要通用 I 和 O)来处理它。

func run<I : Codable, O : Codable>(_ inputType: I, _ outputType: O, _ converter : (_ input: I)-> O) throws -> Void
{ 
    // do something to input I

    let output : O = converter(input)

    // do something else to output O
}

问题是,我无法像示例一样调用此方法:

run(InputObj, OutputObj) { (input) -> Codable in
        var outputObj = OutputObj( ... )
        // do something here
        return outputObj
}

它显示一个错误:

无法将 '() -> Codable' 类型的值转换为 预期参数类型 '() -> _'

我也尝试将块的返回类型“Codable”更改为“OutputObj”。

如果有人可以提供帮助,不胜感激。

【问题讨论】:

    标签: swift generics higher-order-functions


    【解决方案1】:

    你不需要在一个类上让它成为一个方法。您问题中简化代码中的问题是,闭包被显式键入以返回 Codable,但在您的答案中的代码中,它键入返回 OutputObj

    如果您在示例中删除了闭包的显式返回类型——并依赖从inputoutput 参数推断的类型——代码无需进一步修改即可工作。

    try run(inputObj, outputObj) { input in
        // do something and return an output object
    }
    

    此外,还有一些关于 Swift 风格改进的建议:

    • 返回Void 是多余的,因此您可以从run 函数声明中删除它。
    • Swift 通常会尝试描述/命名它的泛型参数。例如,Optional&lt;Wrapped&gt;Array&lt;Element&gt;Dictionary&lt;Key, Value&gt;。在您的情况下,InputOutput 将比 IO 更具描述性。
    • Swift 通常不在类型或变量名称中使用Type 后缀,并且传递给此函数的参数不是类型,它们是值/实例。在这种情况下,inputoutput 将是这两个参数的更惯用名称。
    • 如果从参数类型中可以清楚地看出哪一个是输入,哪一个是输出,则未标记的参数符合 Swift 命名准则。否则,使用标记参数(参数名称前没有 _)调用站点会更清晰。

    通过这些更改,run 函数声明将如下所示:

    func run<Input: Codable, Output: Codable>(input: Input, output: Output, converter: (Input) -> Output) throws
    

    【讨论】:

      【解决方案2】:

      好的!

      我找到了解决此问题的方法。 我为函数“run”创建了一个类

      class Converter<I : Codable, O : Codable> {
          func run(_ converter : (_ input: I)-> O) throws -> Void
      }
      

      然后调用

      let converter : Converter = Converter<InputObj, OutputObj>()
      run() { (input) -> OutputObj in
          var outputObj = OutputObj( ... )
          // do something here
          return outputObj
      }
      

      现在一切正常!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-11
        • 1970-01-01
        • 2020-08-30
        • 2012-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多