swift - 从可选的通用扩展返回 nil

标签 swift generics option-type

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

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

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

我想这样使用:

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

知道如何让它发挥作用吗?

最佳答案

我不认为你可以用一个静态属性来实现这个,但是你可以用一个静态函数来实现它:

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

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

就泛型而言,函数比属性强大得多。


更新 经过一番考虑,你可以拥有静态属性,你只需要在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 的一致性。

关于swift - 从可选的通用扩展返回 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54572369/

相关文章:

swift - 带有 swift 的 Sprite Kit 中的长按识别器

java - 通用限制 hell : Bound Mismatch

generics - 如何在 Rust 中转换泛型原始类型?

java - Java中的Varargs到ArrayList问题

Swift 字符串 vs. 字符串!与字符串?

ios - 为什么 Swift 自定义 UIActivity 图标图像不显示,而 Objective-C 正确显示?

swift - 如何在 CoreVideo 直播 session 中添加交互式 UIView(例如倒数计时器)

swift - 如何在 MessageUI (Swift 4) 中启用按钮

regex - 当没有匹配项或组索引太高时返回 nil

swift - "unexpectedly found nil while unwrapping an Optional value"内部 captureOutput 函数