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

  1. class Pet { }
  2. class Dog: Pet { }
  3. class Cat: Pet { }
  4. // 1. 隐藏具体宠物类型信息
  5. let pets: [Pet] = [Dog(), Cat()]

https://github.com/bignerdranch/type-erasure-playgrounds/blob/master/playgrounds/Pokemon_erasure.playground/Contents.swift

原文地址:https://www.cnblogs.com/feng9exe/p/11978823.html

时间: 2024-10-26 16:37:16

Type Erasure with Pokemon---swift的类型擦除的相关文章

swift类型擦除的定义-swift的类型擦除只是一个类型高低阶转换的游戏。

所谓swift的类型擦除是指: moand转换: 通过技术手段(通常是包装器),将具体类型的类型信息擦除掉了,只将类型的(某一个侧面的)抽象信息(通常指的是类型尊从的协议.接口.或基类)暴露出来. AnyHashable 属于无关联类型的擦除. 将具体类型的类型信息擦除掉了,只将协议类型的信息暴露出来. 类型擦除实践:将相同协议的不同实现屏蔽起来,暴露出类型的共同特征(协议接口). 原文地址:https://www.cnblogs.com/feng9exe/p/10525043.html

Java魔法堂:解读基于Type Erasure的泛型

一.前言 还记得JDK1.4时遍历列表的辛酸吗?我可是记忆犹新啊,那时因项目需求我从C#转身到Java的怀抱,然后因JDK1.4少了泛型这样语法糖(还有自动装箱.拆箱),让我受尽苦头啊,不过也反映自己的水平还有待提高,呵呵.JDK1.5引入了泛型.自动装箱拆箱等特性,C#到Java的过渡就流畅了不少.下面我们先重温两者非泛型和泛型的区别吧! // 非泛型遍历列表 List lst = new ArrayList(); lst.add(1); lst.add(3); int sum = 0; fo

Java-泛型编程-类型擦除(Type Erasure)

Java中的泛型代码和C++中的模板有一个很大的不同:C++中模板的实例化会为每一种类型都产生一套不同的代码,这就是所谓的代码膨胀. Java中并不会产生这个问题.虚拟机中并没有泛型类型对象,所有的对象都是普通类. 虚拟机中的泛型转换需要记住4条事实: 1) 定义任何一个泛型都会自动产生其原始类型(raw type) 2) 这个过程中,泛型类型会被擦除,替换为其限定类型(bounding type) 3) 必要时插入强制转换来保证类型安全 4) 使用桥接方法(bridge method)来保证正

java类型擦除(Java Type Erasure Mechanism)

在JDK5之后java提供了泛型(Java Genertics),允许在定义类的时候使用类型作为参数.泛型广泛应用于各类集合中.本文对其以及其用法进行介绍. 1.一个常见的错误 下面例子中,用List<Object>类型的参数来接收List<String>. public class Main { public static void main(String[] args) throws IOException { ArrayList<String> al = new

swift中的&quot;类型擦除&quot;

在 Swift 的世界中,如果我们将协议称之为国王,那么泛型则可以视作皇后,所谓一山不容二虎,当我们把这两者结合起来使用的时候,似乎会遇到极大的困难.那么是否有一种方法,能够将这两个概念结合在一起,以便让它们成为我们前进道路上的垫脚石,而不是碍手碍脚的呢?答案是有的,这里我们将会使用到类型擦除 (Type Erasure) 这个强大的特性. Protocol 'SpellDelegate' can only be used as a generic constraint because it h

Swift 集合类型(Collection Type) 之 字典(dictionary)(官方文档翻译及总结)

Swift语言提供经典的数组和字典两种集合类型来存储集合数据.数组和字典中存储的数据值类型必须明确.这意味着我们不能把不正确的数据类型插入其中.Swift对显式类型集合的使用确保了我们的代码对工作所需要的类型非常清楚.也让我们在开发中可以早早的找到任何的类型不匹配错误.如果你用变量(var)创建的集合,这些集合就是可变的(增删改).如果用常理创建的,这些集合是不能被操作的. 注意: 如果集合的元素是不变的,那就将集合声明为常量.这样Swift编译器能对你创建的集合做性能优化. 1. 数组(arr

转:有关Java泛型的类型擦除(type erasing)

转载自:拈花微笑 自从Java 5引入泛型之后,Java与C++对于泛型不同的实现的优劣便一直是饭后的谈资.在我之前的很多training中,当讲到Java泛型时总是会和C++的实现比较,一般得出的结论是 Java使用类型擦除(type erasing),泛型信息只在编译时供javac作类型检查用,在编译后便被javac擦除,因此无法被反射 C++使用代码模板实现泛型,即在预处理时会生成类似?list_int?,?list_char?等的泛型类,虽然解决Java的运行时伪泛型的问题,但是会导致编

java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题

java泛型(二).泛型的内部原理:类型擦除以及类型擦除带来的问题 参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首要前提是理解类型擦出(type erasure). Java中的泛型基本上都是在编译器这个层次来实现的.在生成的Java字节码中是不包含泛型中的类型信息的.使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉.这个过程就称为类型

JAVA类型擦除

Java泛型-类型擦除 一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Number>(不可协变),奇怪的ClassCastException等. 正确的使用Java泛型需要深入的了解Java的一些概念,如协变,桥接方法,以及这篇笔记记录的类型擦除.Java泛型的处理几乎都在编译器中进行,编译器生成的bytecode是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程即