Type Erasure with Pokemon---swift的类型擦除
Posted feng9exe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Type Erasure with Pokemon---swift的类型擦除相关的知识,希望对你有一定的参考价值。
我感觉这个是swift的设计缺陷。
类型擦除:解决泛型类型作为公用类型的问题
是抽象的公用机制的一种实现方式。
1)类型擦除并不能解决类型不一致的兼容问题,只能解决类似继承一致性的兼容问题。
2)擦除类型后的抽象类型,其类型信息仍然存在,只是需要保持逻辑一致性。
import Foundation |
|
|
|
|
protocol Pokemon { |
|
associatedtype Power |
|
func attack() -> Power |
|
} |
|
|
|
struct Pikachu: Pokemon { |
|
func attack() -> ?? { |
|
return ??() |
|
} |
|
} |
|
|
|
struct Charmander: Pokemon { |
|
func attack() -> ?? { |
|
return ??() |
|
} |
|
} |
|
|
|
// power types |
|
struct ?? { } |
|
struct ?? { } |
|
|
|
// MARK: - Abstract base class |
|
class _AnyPokemonBase<Power>: Pokemon { |
|
init() { |
|
guard type(of: self) != _AnyPokemonBase.self else { |
|
fatalError("_AnyPokemonBase<Power> instances can not be created; create a subclass instance instead") |
|
} |
|
} |
|
func attack() -> Power { |
|
fatalError("Must override") |
|
} |
|
} |
|
// MARK: - Box container class |
|
fileprivate final class _AnyPokemonBox<Base: Pokemon>: _AnyPokemonBase<Base.Power> { |
|
var base: Base |
|
init(_ base: Base) { self.base = base } |
|
fileprivate override func attack() -> Base.Power { |
|
return base.attack() |
|
} |
|
} |
|
// MARK: - AnyPokemon Wrapper |
|
final class AnyPokemon<Power>: Pokemon { |
|
private let box: _AnyPokemonBase<Power> |
|
init<Base: Pokemon>(_ base: Base) where Base.Power == Power { |
|
box = _AnyPokemonBox(base) |
|
} |
|
func attack() -> Power { |
|
return box.attack() |
|
} |
|
} |
|
|
|
// Use AnyPokemon type directly |
|
let pokemon: AnyPokemon = AnyPokemon(Pikachu()) |
|
pokemon.attack() |
|
|
|
// Add a new electric Pokemon |
|
class Jolteon: Eevee, Pokemon { |
|
func attack() -> ?? { |
|
return ??() |
|
} |
|
} |
|
class Eevee {} |
|
|
|
// Iterate over a collection of Electric Pokemon |
|
let electricPokemon = [AnyPokemon(Pikachu()), AnyPokemon(Jolteon())] |
|
electricPokemon.map() { $0.attack() } |
- class Pet { }
- class Dog: Pet { }
- class Cat: Pet { }
- // 1. 隐藏具体宠物类型信息
- let pets: [Pet] = [Dog(), Cat()]
https://github.com/bignerdranch/type-erasure-playgrounds/blob/master/playgrounds/Pokemon_erasure.playground/Contents.swift
以上是关于Type Erasure with Pokemon---swift的类型擦除的主要内容,如果未能解决你的问题,请参考以下文章
java类型擦除(Java Type Erasure Mechanism)
C++Breaking Dependencies: Type Erasure - A Design Analysis - Klaus Iglberger - CppCon 2021 - 知识点目录