Skip to content

Latest commit

 

History

History
100 lines (77 loc) · 3.92 KB

5.5.4 AnyvsSome.md

File metadata and controls

100 lines (77 loc) · 3.92 KB

any vs some

  1. Design protocol interfaces in Swift
  2. Understanding type erasure in Swift
  3. Base: any and some

"Мне все равно, что используется для этого типа, если он соответствует этому протоколу" - some и any.

Как объяснили инженеры Apple, экзистенциальный тип похож на коробку, в которой находится что-то, соответствующее определенному протоколу:

any vs some

Для компилятора экзистенциальный тип — это просто «коробка», он понятия не имеет, что внутри коробки.

  • any ключевое слово просто аннотирует, что данный тип является экзистенциальным типом. any — это возможность динамически заменять реализацию во время выполнения, присваивая ей новое значение другого конкретного типа Протокола (чего мы не смогл быи сделать если бы она определена как let). any типы мы не можем сравнить.

  • при some (opaque type) мы знаем с каким мы типом работаем, но не хотим его показывать наружу. То есть сохраняется идентичность типа: компилятор имеет доступ к информации о типе, но для использующих метод возвращается протокол (тип закрыт протоколом). some типы мы можем сравнивать.

Example

Any:

protocol Vehicle {
    var name: String { get }

    associatedtype FuelType
    func fillGasTank(with fuel: FuelType)
}

struct Car: Vehicle {
    let name = "car"
    func fillGasTank(with fuel: Gasoline) {
        print("Fill \(name) with \(fuel.name)")
    }
}

struct Bus: Vehicle {
    let name = "bus"
    func fillGasTank(with fuel: Diesel) {
        print("Fill \(name) with \(fuel.name)")
    }
}

struct Gasoline { let name = "gasoline" }

struct Diesel { let name = "diesel" }

// ✅ No compile error when changing the underlying data type
var myCar: any Vehicle = Car()
myCar = Bus()
myCar = Car()

// ✅ No compile error when returning different kind of concrete type 
func createAnyVehicle(isPublicTransport: Bool) -> any Vehicle {
    if isPublicTransport {
        return Bus()
    } else {
        return Car()
    }
}

Some #1:

// 🚫 compile error when changing the underlying data type
var myCar: some Vehicle = Car()
myCar = Bus()
myCar = Car()

// 🚫 compile error when returning different kind of concrete type 
func createAnyVehicle(isPublicTransport: Bool) -> some Vehicle {
    if isPublicTransport {
        return Bus()
    } else {
        return Car()
    }
}

Some #2:

 // ✅ No compile error when changing the underlying data type
var myCar: any Vehicle = Car()
myCar = Bus()
myCar = Car()

// ✅ No compile error when returning equal kind of concrete type 
func createAnyVehicle(isPublicTransport: Bool) -> some Vehicle {
    if isPublicTransport {
        return Car()
    } else {
        return Car()
    }
}

5.5.3 Existential Types Theme | Back To iOSWiki Contents | 5.6 Method Dispatch Theme Folder