func myfunc<T>(i:T) -> T {
return i
}
是否可以使这个泛型函数成为闭包?
let myfunc = { <T>(i:T) -> T in
return i
}
这不起作用......
答案 0 :(得分:13)
不,因为变量和表达式不是通用的。只有通用函数和泛型类型。
澄清一下:在某些语言中,您可以使用通用量词的类型,例如forall a. a -> a
。但在Swift中,类型不能具有通用量词。因此表达式和值本身不是通用的。函数声明和类型声明可以是通用的,但是当您使用这样的泛型函数或这种泛型类型的实例时,会选择某种类型(可以是实数类型或类型变量)作为类型参数,然后你得到的价值不再是通用的。
答案 1 :(得分:6)
可能您需要这样的东西。
类型声明:
typealias ResultClosure<T> = (ResultCode, String?, T?) -> Void
函数声明:
func loginUser(userName: String, password: String, resultHandler: ResultClosure<TokenModel>?)
用法:
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)
}
}
答案 2 :(得分:0)
我找到了另一种方法,您可以在闭包中使用Anyobject并将任何值传递给您的方法。
typealias genericCompletion<T:AnyObject> = ((Bool,T,String) -> Void)
struct Student {
var name:String = "Kishore"
var age : String = "125"
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.createAGenericReturn { (success, object, message) in
}
self.createStructGeneric { (success, student, message) in
}
}
func createAGenericReturn(callback:@escaping(genericCompletion<AnyObject>)){
callback(true,434.433 as AnyObject,"kishoreTest")
}
func createStructGeneric(callback:@escaping(genericCompletion<AnyObject>)){
callback(true,Student.init() as AnyObject,"kishoreTest")
}
}
在这里您可以看到我提到Generic as Anyobject typealias genericCompletion =((Bool,T,String)-> Void),因此您可以将任何值传递给它。
答案 3 :(得分:0)
如前所述,Swift中的变量不能为通用变量,因此无法创建由调用者指定其通用类型的闭包。但是,有一些解决方法:
使用SE-253,可以使任意(名义)类型可调用。因此,我们可以声明一个具有通用callAsFunction
方法的(非通用)结构,而不是声明一个通用闭包:
struct MyFunc {
func callAsFunction<T>(_ i: T) -> T {
return i
}
}
现在,我们可以声明一个可以使用通用值调用的非通用变量:
let myFunc = MyFunc()
let x = myFunc(42) // -> Int
let y = myFunc("foo") // -> String
请注意,此变通办法并不适用于所有情况,但在某些情况下可能会有所帮助。