是否可以在Swift中创建一个通用的闭包?

Ken*_*ang 24 generics closures ios swift

func myfunc<T>(i:T) -> T {
    return i
}
Run Code Online (Sandbox Code Playgroud)

是否有可能使这个泛型函数成为一个闭包?

let myfunc = { <T>(i:T) -> T in
    return i
}
Run Code Online (Sandbox Code Playgroud)

这不起作用......

new*_*cct 14

不,因为变量和表达式不能是通用的.只有通用函数和泛型类型.


澄清一下:在某些语言中,您可以使用具有通用量词的类型,例如forall a. a -> a.但在Swift中,类型不能具有通用量词.因此表达式和值本身不是通用的.函数声明和类型声明可以是通用的,但是当您使用这样的泛型函数或这种泛型类型的实例时,会选择某种类型(可以是实数类型或类型变量)作为类型参数,然后你得到的价值不再是通用的.


Kon*_*nok 10

可能你需要这样的东西。

类型声明:

typealias ResultClosure<T> = (ResultCode, String?, T?) -> Void
Run Code Online (Sandbox Code Playgroud)

函数声明:

func loginUser(userName: String, password: String, resultHandler: ResultClosure<TokenModel>?)
Run Code Online (Sandbox Code Playgroud)

用法:

    NetConnector.shared.loginUser(userName: userName ?? "", password: password ?? "") { (code, message, data) in
        self.display?.unlockScreen()
        if code == .success {
            if let activeToken = data {
                AppData.shared.userToken = activeToken
            }
            self.display?.showHome()
        } else {
            self.display?.showError(errorMessage: message)
        }
    }
Run Code Online (Sandbox Code Playgroud)


Pal*_*lle 6

如前所述,Swift 中的变量不能是泛型的,因此不可能创建一个由调用者指定其泛型类型的闭包。但是,有一些解决方法:

使用SE-253,可以调用任意(标称)类型。因此,我们可以声明一个具有泛型callAsFunction方法的(非泛型)结构体,而不是声明泛型闭包:

struct MyFunc {
    func callAsFunction<T>(_ i: T) -> T {
        return i
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我们可以声明一个非泛型变量,我们可以使用泛型值调用它:

let myFunc = MyFunc()
let x = myFunc(42) // -> Int
let y = myFunc("foo") // -> String
Run Code Online (Sandbox Code Playgroud)

请注意,此解决方法并不适用于所有情况,但在某些情况下可能会有所帮助。