[英]Swift generic class initializer
I found a problem with designing result class in swift 我发现快速设计结果类存在问题
struct Result<T>{
private let data: T?
let error: NSError?
var isSuccess: Bool {
get {
return data != nil
}
}
init(data: T) {
self.data = data
self.error = nil
}
init(error: NSError) {
self.data = nil
self.error = error
}
}
Usage should look like this 用法应如下所示
Result(data: "something") // T as string
The problem occurs when I want to pass an error 当我想传递错误时出现问题
Result(error: errorFromSomewhere) //T is not specified
Below is real application usage: 以下是实际的应用程序用法:
class ParseRegistrationProvider: RegistrationProvider {
func register(model: RegistrationForm) -> Promise<Result<String>> {
return Promise { accept, reject in
let user = PFUser()
user.username = model.nickName
user.password = model.password
user.email = model.emailAdreess
user.signUpInBackgroundWithBlock({ (isSuccess, error) -> Void in
if isSuccess {
accept(Result(data: "OK"))
} else {
var errorResult = Result(error: error!) //causes error
reject(errorResult)
}
})
}
}
}
"errorResult" causes compiler error: “ errorResult”导致编译器错误:
Generic parameter T could not be inferred
无法推断出通用参数T
Update: this approch works correctly: 更新:此方法正常工作:
Result<String>(error: errorFromSomewhere)
I'd like to suggest to use variant type for Result like this cause it is more compact and can be used in pattern matching naturally: 我想建议对Result使用变量类型,因为这样会更紧凑,并且可以自然地用于模式匹配:
enum Result<T>{
case Data(T?)
case Error(NSError)
var isSuccess: Bool{
get{
switch self{
case .Data(_?):
return true
default:
return false
}
}
} }
Your code may become like this: 您的代码可能如下所示:
class ParseRegistrationProvider: RegistrationProvider {
func register(model: RegistrationForm) -> Promise<Result<String>> {
return Promise { accept, reject in
let user = PFUser()
user.username = model.nickName
user.password = model.password
user.email = model.emailAdreess
user.signUpInBackgroundWithBlock({ (isSuccess, error) -> Void in
if isSuccess {
accept(Result<String>.Data("OK"))
} else {
var errorResult = Result<String>(error: error!) //causes error
reject(errorResult)
}
})
}
}
} }
When you use classes instead of structs, you can define one base class (eg ErrorResult
with init(error: NSError)
) and one derived Result<T>
) with init(data: T)
). 当使用类而不是结构时,可以定义一个基类(例如,带有
init(error: NSError)
ErrorResult
,以及带有init(data: T)
一个派生的Result<T>
)。
This way, you entirely side-step the generic parameter. 这样,您就完全避开了通用参数。 However, you potentially add some run-time overhead because of using a class.
但是,由于使用类,可能会增加一些运行时开销。
To answer your question directly, you could just declare errorResult as: 要直接回答您的问题,您可以将errorResult声明为:
var errorResult : Result<String>
That would fix the problem immediately. 那将立即解决问题。 However, I think the better solution is to use an enum instead of a struct as it is more appropriate (unless there is more to it than you posted).
但是,我认为更好的解决方案是使用枚举而不是结构,因为它更合适(除非它比您发布的内容多)。
enum Result<T> {
case Data(T)
case Error(NSError)
var success : Bool {
switch self {
case .Data:
return true
case .Error:
return false
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.