Ограничение типа Необязательное расширение, видимое для других типов - PullRequest
0 голосов
/ 20 ноября 2018

Так как мне надоело вручную нилитировать необязательные значения, я решил превратить общие значения по умолчанию в удобные и простые в использовании расширения в Optional, как показано ниже:

public extension Optional {
    var exists: Bool { return self != nil }
}

public extension Optional where Wrapped == String {
    var orEmpty: Wrapped { return self ?? "" }
}

public extension Optional where Wrapped == Int {
    var orZero: Wrapped { return self ?? 0 }
}

public extension Optional where Wrapped == Double {
    var orZero: Wrapped { return self ?? 0 }
}

public extension Optional where Wrapped == Float {
    var orZero: Wrapped { return self ?? 0 }
}

public extension Optional where Wrapped == Bool {
    var orFalse: Wrapped { return self ?? false }
}

Моя проблема возникает при попытке использовать их для необязательного значения определенного типа.
Я могу вызвать .orZero для переменной типа String? и получить одну из следующих ошибок:

Неоднозначная ссылка на члена 'orZero'
'String?'не конвертируется в 'Optional'

Я хотел бы знать, почему XCode предоставляет свойства .orZero такого необязательного параметра, как допустимые параметры автозаполнения?Я бы подумал, что общие ограничения помешают мне их увидеть.
Для чего бы то ни было, я использую Xcode 10.1 и Swift 4.2

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

.orZero в качестве автозаполнения является ошибкой.Это можно обойти, переписав свои расширения с точки зрения соответствующих литеральных протоколов.

public extension Optional where Wrapped: ExpressibleByIntegerLiteral {
    var orZero: Wrapped { return self ?? 0 }
}

public extension Optional where Wrapped: ExpressibleByBooleanLiteral {
    var orFalse: Wrapped { return self ?? false }
}

Таким образом, Swift теперь может выяснить, что .isZero не следует предлагать для, т. Е. Переменной типаString?, и если вы все равно попытаетесь вызвать его, он выдаст ошибку Type 'String' does not conform to protocol 'ExpressibleByIntegerLiteral'.

0 голосов
/ 20 ноября 2018

Взгляните на это .

В вашем расширении .orZero только для Int, Float, Double.

Для String у вас есть .orEmpty.

...