swift中的"类型擦除"

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

Protocol ‘SpellDelegate‘ can only be used as a generic constraint because it has Self or associated type requirements

因为swift泛型还不支持逆变和协变也就不会有真的类型擦除,而这里说的"类型擦除"是指:利用一个具体实现的通用泛型类(参看系统库的AnySequence),去包装具体实现了该泛型协议的类。用以解决不能直接使用泛型协议进行变量定义的问题。具体可以看这篇文章

那个ppt的代码看着不方便,我就简化了一下:

protocol Erasable {
    associatedtype DataType

    func foo(arg: DataType) -> DataType
}

class AnyErasable<EraseType>: Erasable {
    private var fooFunc: (EraseType) -> EraseType

    init<Inject: Erasable>(_ obj: Inject) where Inject.DataType == EraseType {
        fooFunc = obj.foo
    }

    func foo(arg: EraseType) -> EraseType {
        return fooFunc(arg)
    }
}

class MyEraseClass: Erasable {
    func foo(arg: Int) -> Int {
        return arg * 10
    }
}

class MyEraseDelegate<T> {
    var val: T
    // var delegate: Erasable  -- 编译失败
    var delegate: AnyErasable<T>?

    init(_ val: T) {
        self.val = val
    }

    func doSomething() -> T {
        return (delegate?.foo(arg: val))!
    }
}

let test = MyEraseDelegate(35)
test.delegate = AnyErasable(MyEraseClass())
print("result: \(test.doSomething())")  // 350

作者:fuadam1982
链接:https://www.jianshu.com/p/a852865f94fc
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

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

时间: 2024-10-10 10:42:56

swift中的"类型擦除"的相关文章

Swift中基本类型的转换

最近上手学习了Swift的语言,谙习JS的我感觉非常顺眼,在此记录下我的学习过程吧. 因为我对Objective-c接触的不多,所以在oc里头使用的东西目前我可能还有很多不知道他的存在. 最近在用swift写了一些小示例app,很多地方都用到了基本类型的转换,但是我发现他居然没有Integer.parse()这样的东西,所以还是摸索了一番. ps: 我使用的版本是xCode6 bate4(其他版本可能实现又差别) OK,talk is chaep, show you the code! 扩展Do

Swift中的类型属性(静态变量)

http://blog.haohtml.com/archives/15098 Swift中的类型属性(静态变量) Posted on 2014/06/13 类型属性语法 在 C 或 Objective-C 中,静态常量和静态变量的定义是通过特定类型加上global关键字.在 Swift 编程语言中,类型属性是作为类型定义的一部分写在类型最外层的花括号内,因此它的作用范围也就在类型支持的范围内. 使用关键字static来定义值类型的类型属性,关键字class来为类(class)定义类型属性.下面的

Java中泛型 类型擦除

转自:Java中泛型是类型擦除的 Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉,看下面一个列子,代码如下: public class Foo { public void listMethod(List<String> stringList){ } public void listMethod(List<Integer> intList) {

JAVA泛型中的类型擦除及为什么不支持泛型数组

一,数组的协变性(covariant array type)及集合的非协变性 设有Circle类和Square类继承自Shape类. 关于数组的协变性,看代码: public static double totalArea(Shape[] arr){ double total = 0; for (Shape shape : arr) { if(shape != null) total += shape.area(); } return total; } 如果给 totalArray(Shape[

泛型中的类型擦除

通过反射理解泛型的本质(类型擦除) Java中的泛型是通过类型擦除来实现的.所谓类型擦除,是指通过类型参数合并,将泛型类型实例关联到同一份字节码上.编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上.类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法. 下面通过两个例子来证明在编译时确实发生了类型擦除. 例1分别创建实际类型为String和Integer的ArrayList对象,通过getClass()方法获取两个实例的类,最后判断这个

Java中的类型擦除与桥方法

类型擦除 Java在语法中虽然存在泛型的概念,但是在虚拟机中却没有泛型的概念,虚拟机中所有的类型都是普通类.无论何时定义一个泛型类型,编译后类型会被都被自动转换成一个相应的原始类型. 比如这个类 public class Parent<T> { public void sayHello(T value) { System.out.println("This is Parent Class, value is " + value); } } 在编译后就变成了 public c

Swift中可选类型(Optional)的用法 以及? 和 ! 的区别 (转载博客,知识分享)

本文转载自:代码手工艺人的博客,原文名称:Swift之 ? 和 ! Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化.如果在使用变量之前不进行初始化就会报错: C代码   var stringValue : String //error: variable 'stringValue' used before being initialized //let hashValue = stringVa

Swift学习-----可选类型

可选类型 * 可选类型表示变量可以有值, 也可以没有值 * C 和 Objective-C 中并没有可选类型这个概念 * Swift中只有可选类型才可以赋值为nil * 如果你声明一个可选常量或者变量但是没有赋值,它们会自动被设置为nil * 格式: Optional<类型> 或 在类型后面加上?号 可选类型的取值是一个枚举 * None 没有值 * Some 有值 * 由于可选类型在Swift中随处可见, 所以系统做了一个语法糖, 在类型后面加上? 注意: * nil不能用于非可选的常量和变

Swift 语言附注 类型

本页包含内容: 类型注解(Type Annotation) 类型标识符(Type Identifier) 元组类型(Tuple Type) 函数类型(Function Type) 数组类型(Array Type) 可选类型(Optional Type) 隐式解析可选类型(Implicitly Unwrapped Optional Type) 协议合成类型(Protocol Composition Type) 元类型(Metatype Type) 类型继承子句(Type Inheritance C