Ответ
Да, можно создать свой тип, аналогичный Optional. Для этого используется enum с двумя случаями, как и у встроенного типа.
Базовая реализация:
enum MyOptional<Wrapped> {
case some(Wrapped)
case none
// Аналог map для Optional
func map<U>(_ transform: (Wrapped) -> U) -> MyOptional<U> {
switch self {
case .some(let value):
return .some(transform(value))
case .none:
return .none
}
}
// Аналог flatMap
func flatMap<U>(_ transform: (Wrapped) -> MyOptional<U>) -> MyOptional<U> {
switch self {
case .some(let value):
return transform(value)
case .none:
return .none
}
}
}
Особенности кастомной реализации:
- Generic-тип
Wrappedпозволяет хранить любое значение. - Реализация основных методов —
map,flatMap,filter. - Синтаксический сахар можно добавить через расширения (например, инициализатор для неявного обертывания).
- Нет специальной поддержки компилятора — встроенный
Optionalимеет оптимизации и синтаксис (?,!), недоступные для пользовательских типов.
Пример использования:
let myValue: MyOptional<Int> = .some(10)
let squared = myValue.map { $0 * $0 } // .some(100)
let empty: MyOptional<Int> = .none
let result = empty.map { $0 * 2 } // .none