Возврат ноля из необязательного общего расширения - PullRequest
0 голосов
/ 07 февраля 2019

Вот кое-что, с чем я играю.Проблема в том, что у меня есть контейнерный класс, который имеет универсальный аргумент, который определяет тип, возвращаемый из замыкания.Я хочу добавить функцию, которая доступна только в том случае, если универсальный тип является необязательным, и эта функция возвращает экземпляр, содержащий ноль.

Вот код, с которым я сейчас играю (который не будет компилироваться):

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

Есть идеи, как заставить это работать?

1 Ответ

0 голосов
/ 07 февраля 2019

Я не думаю, что вы можете достичь этого с помощью статического свойства, однако вы можете достичь этого с помощью статической функции:

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.

...