当前位置: 首页 > 面试题库 >

Swift泛型不保留类型

微生俊捷
2023-03-14
问题内容

我正在尝试基于指定的泛型类型进行强制转换和/或生成一个变量。我知道并没有快速的类型擦除,但是除了泛型的指定条件(例如符合基类)外,泛型似乎并没有保留类型。看来我可以强制转换或初始化的只是基类。更奇怪的是,当我在调试器中时,泛型似乎对正确的类具有RawPointer,甚至变量看起来都像是正确的类型:

编辑:

从Xcode 6.1开始,这仍然是一个问题(简化的代码由Gregory Higley提供):

class BaseClass {
    func printme() -> Void {
        println("I am BaseClass")
    }
}

class DerivedClass : BaseClass {
    override func printme() -> Void {
        println("I am DerivedClass")
    }
}

class Util<T: BaseClass> {
    func doSomething() {
        var instance = T()
        instance.printme()
    }
}

var util = Util<DerivedClass>()
util.doSomething()

仍打印出“我是BaseClass”

还需要注意的是,基类中必需的init {}不再起作用。

在此处输入图片说明


问题答案:

此代码按预期方式工作。

class BaseClass {

    required init() {} // <-- ADDED THIS

    func printme() -> Void {
        println("I am BaseClass")
    }
}

class DerivedClass : BaseClass {
    override func printme() -> Void {
        println("I am DerivedClass")
    }
}

class Util<T: BaseClass> {
    func doSomething() {
        var instance = T()
        instance.printme()
    }
}

var util = Util<DerivedClass>()
util.doSomething()

代码库从@GregoryHigley答案中被窃取了:)

标记init() {}required事物。这保证init()ANY 派生类的指定初始化器BaseClass

没有它,人们可能会制造出非法的子类,例如:

class IllegalDerivedClass : BaseClass {
    var name:String

    init(name:String) {
        self.name = name
        super.init()
    }

    override func printme() -> Void {
        println("I am DerivedClass")
    }
}

var util = Util<IllegalDerivedClass>()
util.doSomething()

您知道这是行不通的,因为IllegalDerivedClass
它不继承init()初始值设定项。

我认为,这就是您遇到问题的原因。

反正那是谁的错

  • 编译器 应警告歧义。
  • 运行时 应该尝试初始化DerivedClass()与指定T
  • 调试器 应显示instance实际的实例BaseClass

添加:

从Xcode 6.1 GM 2开始,看来您需要做更多的工作。(除了required init() {}

class Util<T: BaseClass> {
    let theClass = T.self // store type itself to variable

    func doSomething() {
        var instance = theClass() // then initialize
        instance.printme()
    }
}

我绝对不知道为什么我们需要这个,X发生了什么(

添加:2014/10/18

我发现这也有效:

    func doSomething() {
        var instance = (T.self as T.Type)()
        instance.printme()
    }

添加:2015/02/10

从Xcode 6.3(6D520o)/ Swift 1.2开始

我们不再需要(T.self as T.Type)()hack。只要具有初始化程序就T()可以工作。T``required init()

class Util<T: BaseClass> {
    func doSomething() {
        var instance = T()
        instance.printme()
    }
}


 类似资料:
  • 问题内容: 我正在编写一些Swift代码,其中有一个包含通用类型的数组: 稍后在我的代码中,我需要确定存储在数组中的类型。我尝试使用文档中描述的类型转换技术(尽管泛型没有使用过)。 上面的switch语句在编译时导致以下错误: 发出IR SIL功能@ _TFC19Adder_Example Mac6Matrix9transposeUS 7ElementfGS0_Q__FT_GSqGS0_Q___以

  • Swift 4语言提供了泛型()功能来编写灵活且可重用的函数和类型。 泛型用于避免重复并提供抽象。 Swift 4标准库使用泛型代码构建。 Swift 4中的数组和字典类型属于泛型集合。 使用数组和字典,数组可定义为保存值和值或任何其他类型。 示例代码 当使用playground运行上述程序时,得到以下结果 - 泛型函数:类型参数 泛型函数可用于访问任何数据类型,如或。 当使用playground

  • Swift 提供了泛型让你写出灵活且可重用的函数和类型。 Swift 标准库是通过泛型代码构建出来的。 Swift 的数组和字典类型都是泛型集。 你可以创建一个Int数组,也可创建一个String数组,或者甚至于可以是任何其他 Swift 的类型数据数组。 以下实例是一个非泛型函数 exchange 用来交换两个 Int 值: 实例// 定义一个交换两个变量的函数 func swapTwoInts

  • 问题内容: 我正在尝试使用泛型动态创建基于实例的类型,但是在类自省时遇到了困难。 这里是问题: 有一个Swift相当于Obj-C的吗? 有没有办法使用from 的结果实例化一个类? 有没有一种方法可以严格从通用参数获取信息或以其他方式键入信息?(类似于C#的语法) 问题答案: 那么,对于一个,雨燕等同的IS (见元类型的文档,但他们非常薄)。 实际上,它甚至都不起作用!您必须使用。 同样,我尝试了

  • #include <stdio.h> union Type { int a; int *b; }; int main() { printf("sizeof(union Type) is %lu\n", sizeof(union Type)); return 0; } 技巧 使用gcc -g编译生成的程序,是不包含union Type的符号信息: (gdb) p sizeof(

  • 问题内容: 是否可以为特殊/构造的泛型类型扩展泛型类?我想使用一种方法来扩展Int Arrays,以计算其元素的总和。 例如 问题答案: Swift 5.x: