簡體   English   中英

快速通用類型函數+高階函數

[英]Swift Generic Type in Function + Higher Order Function

假設我有一個通用方法來進行一些轉換,該轉換需要一個Input和一個Output,部分流程需要一個塊(也需要通用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”更改為“ OutputObj”。

感謝任何人都可以提供幫助。

您無需將此作為類的方法。 問題中的簡化代碼中的問題是,顯式鍵入了閉包以返回Codable但答案中的代碼中鍵入了閉包以返回OutputObj

如果您在示例中刪除了閉包的顯式返回類型,並且依賴於從inputoutput參數推斷出的類型,則代碼無需進一步修改即可工作。

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

此外,一些改進Swift風格的建議:

  • 返回Void是多余的,因此您可以將其從run函數聲明中刪除。
  • Swift通常嘗試描述/命名其通用參數。 例如, Optional<Wrapped>Array<Element>Dictionary<Key, Value> 在您的情況下, InputOutputIO更具描述性。
  • Swift通常在類型或變量名稱中不使用Type后綴,並且傳遞給此函數的參數不是類型,它們是值/實例。 在這種情況下, inputoutput將是兩個參數的更多慣用名稱。
  • 如果從參數類型中可以清楚看出,哪個是輸入,哪個是輸出,則未標記的參數將與Swift命名准則匹配。 否則,呼叫站點將帶有帶標簽的參數(在參數名稱前沒有_ )更清晰。

經過這些更改, run函數聲明將如下所示:

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

好!

我找到了解決此問題的方法。 我為函數“運行”創建一個類

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
}

現在一切都可以完美運行!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM