Swift泛型类初始值设定项

Swift泛型类初始值设定项,swift,Swift,我发现在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

我发现在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
    }
}
当我想传递错误时,问题就出现了

Result(error: errorFromSomewhere) //T is not specified
下面是应用程序的实际使用情况:

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)
                }
            })
        }
    }
}
类ParseRegistrationProvider:RegistrationProvider{
func寄存器(型号:RegistrationForm)->Promise{
返回承诺{在中接受、拒绝
let user=PFUser()
user.username=model.昵称
user.password=model.password
user.email=model.emailAddress
user.SignupInBackgroundithBlock({(isSuccess,error)->中的Void
如果成功{
接受(结果(数据:“OK”))
}否则{
var errorResult=Result(错误:error!)//导致错误
拒绝(错误结果)
}
})
}
}
}
“errorResult”导致编译器错误:

无法推断泛型参数T

更新: 这种方法是正确的:

Result<String>(error: errorFromSomewhere)
结果(错误:errorfromwhere)

当您使用类而不是结构时,您可以使用
init(error:NSError)
定义一个基类(例如
ErrorResult
),使用
init(data:T)
定义一个派生的
Result

这样,您就完全避开了泛型参数。
但是,由于使用类,您可能会增加一些运行时开销。

我建议对这样的结果使用variant type,因为它更紧凑,可以自然地用于模式匹配:

enum Result<T>{
    case Data(T?)
    case Error(NSError)
    var isSuccess: Bool{
        get{
            switch self{
            case .Data(_?):
                return true
            default:
                return false
            }
          }
    } }
枚举结果{
病例数据(T?)
案例错误(N错误)
var isSuccess:Bool{
得到{
切换自身{
案例数据(?):
返回真值
违约:
返回错误
}
}
} }
您的代码可能会变成这样:

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)
                }
            })
        }
    }
类ParseRegistrationProvider:RegistrationProvider{
func寄存器(型号:RegistrationForm)->Promise{
返回承诺{在中接受、拒绝
let user=PFUser()
user.username=model.昵称
user.password=model.password
user.email=model.emailAddress
user.SignupInBackgroundithBlock({(isSuccess,error)->中的Void
如果成功{
接受(结果数据(“确定”))
}否则{
var errorResult=Result(错误:error!)//导致错误
拒绝(错误结果)
}
})
}
}

}要直接回答您的问题,您可以将errorResult声明为:

var errorResult : Result<String>
var errorResult:Result
这将立即解决问题。 但是,我认为更好的解决方案是使用enum而不是struct,因为它更合适(除非它比您发布的内容更多)

枚举结果{
病例数据(T)
案例错误(N错误)
var成功:Bool{
切换自身{
案例.数据:
返回真值
案例.错误:
返回错误
}
}
}

您看到错误的背景是什么?(根据错误消息,它似乎与此结构无关,与使用它的上下文更相关)。@nhgrif我已更新了问题。您还更改了编译器错误消息。当您初始化为
Result(error:error!)
时,在相同的上下文中会发生什么情况,
reject()函数的签名是什么?它期望的参数类型是什么?请注意,这不是生成
Result
的好方法。Swift社区中有大量关于
Result
的工作(请参阅以获得非常好的结果)。如果您要构建自己的(这很好;我一直都在这么做),您希望它是一个枚举,而不是一个结构。@razor118发布一个自我回答比在更新中编辑要好。
var errorResult : Result<String>
enum Result<T> {
    case Data(T)
    case Error(NSError)

    var success : Bool {
        switch self {
        case .Data:
            return true
        case .Error:
            return false
        }
    }
}