从可选的通用扩展名返回nil

时间:2019-02-07 11:30:37

标签: swift generics optional

这是我正在玩的东西。问题是我有一个具有通用参数的容器类,该通用参数定义了从闭包返回的类型。我想添加一个仅在泛型类型为可选并且该函数返回包含nil的实例的情况下可用的函数。

这是我当前正在使用的代码(无法编译):


    jwt.verify(token, process.env.APP_SECRET, (err,userId) => {
                if(err)
          res.send({msg:"your_redirect_loaction_for_login_the_user_again"})
                } else {
                 // user verified
                 req.userId = userId
                }
            })

我想这样使用:

open class Result<T>: Resolvable {

    private let valueFactory: () -> T

    fileprivate init(valueFactory: @escaping () -> T) {
        self.valueFactory = valueFactory
    }

    func resolve() -> T {
        return valueFactory()
    }
}

public protocol OptionalType {}
extension Optional: OptionalType {}

public extension Result where T: OptionalType {

    public static var `nil`: Result<T> {
        return Result<T> { nil } // error: expression type 'Result<T>' is ambiguous without more context
    }
}

有什么主意要怎么做吗?

1 个答案:

答案 0 :(得分:1)

我认为您不能通过静态属性来实现,但是可以通过静态函数来实现:

extension Result {
    static func `nil`<U>() -> Result where T == U? {
        return .init { nil }
    }
}

let x: Result<Int?> = .nil()

泛型时,函数比属性强大得多。


更新经过一番考虑,您可以拥有static属性,只需要将关联的类型添加到OptionalType,这样您就可以知道该类型具有哪些可选通用参数:

protocol OptionalType {
    associatedtype Wrapped
}

extension Optional: OptionalType { }

extension Result where T: OptionalType {
    static var `nil`: Result<T.Wrapped?> {
        return Result<T.Wrapped?> { nil }
    }
}

let x: Result<Int?> = .nil

一个小缺点是,从理论上讲,它使任何类型的类型都可以与OptionalType保持一致。