Swift泛型类初始化器

时间:2016-01-07 13:50:38

标签: 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
    }

    init(error: NSError) {
        self.data = nil
        self.error = error
    }
}

用法应如下所示

Result(data: "something") // T as string

当我想传递错误时会出现问题

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)
                }
            })
        }
    }
}

“errorResult”导致编译器错误:

  

无法推断通用参数

更新: 这个approch工作正常:

Result<String>(error: errorFromSomewhere)

3 个答案:

答案 0 :(得分:1)

我想建议在结果中使用变体类型,因为它更紧凑,可以自然地用于模式匹配:

<script>
    $('.teal.button')
      .popup({
        on: 'click'
      })
    ;
</script>

您的代码可能会变成这样:

enum Result<T>{
    case Data(T?)
    case Error(NSError)
    var isSuccess: Bool{
        get{
            switch self{
            case .Data(_?):
                return true
            default:
                return false
            }
          }
    } }

}

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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
        }
    }
}