泛型与Swift中的T型通话

前端之家收集整理的这篇文章主要介绍了泛型与Swift中的T型通话前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我的应用程序中,我想创建一个通用的方法,它创建一个给定类型T的对象依赖的数组.

我创建了以下功能

func getArray<T : ROJSONObject>(key:String) -> T[] {
    var elements = T[]()

    for jsonValue in getValue(key).array! {
        var element = T()

        element.jsonData = jsonValue
        elements.append(element)
    }

    return elements
}

现在我想在调用方法时传递类型,所以它知道应该在内部创建哪个类型.我认为在Java和C#中,你可以使用这样的方法

object.getArray<Document>("key")

当我这样称呼,我总是得到错误

Cannot explicitly specialize a generic function

所以我的修复是定义一个附加参数,包含一个类型T的实例,所以它会自动检测类型:

func getArray<T : ROJSONObject>(key:String,type:T) -> T[] {
    var elements = T[]()

    for jsonValue in getValue(key).array! {
        var element = T()

        element.jsonData = jsonValue
        elements.append(element)
    }

    return elements
}

在没有传递未使用的实例的情况下,真的没有其他方法来获得这种行为吗?还是我误解的东西?

进一步测试

在jtbandes的答案之后,我做了一些更多的测试.我试图通过在呼叫中添加as来强制类型.

class Person {

    init() { }

    func getWorkingHours() -> Float {
        return 40.0
    }
}

class Boss : Person {
    override func getWorkingHours() -> Float {
        println(100.0)
        return 100.0
    }
}

class Worker : Person {
    override func getWorkingHours() -> Float {
        println(42.0)
        return 42.0
    }
}

func getWorkingHours<T : Person>() -> T {
    var person = T()
    person.getWorkingHours()

    return person
}

var worker:Worker = getWorkingHours() as Worker
var boss:Boss = getWorkingHours() as Boss
worker.getWorkingHours() // prints out 40.0 instead of 42.0
boss.getWorkingHours() // prints out 40.0 instead of 100.0

所以不知何故,类型始终是基本类型,即使我已经指定了具有as关键字的类型.我知道这个例子没有什么意义,但它只是用于测试目的.

我认为这是一个bug.

您可以通过将类作为NSObject的子类或使用@required标记基类的构造函数解决此问题

import Cocoa

class A : NSObject {
    init() { }
}
class B : A {}
class C : A {}

func Create<T:NSObject> () -> T {
    return T()
}

println(Create() as A)
println(Create() as B)
println(Create() as C)

//<_TtC11lldb_expr_01A: 0x7f85ab717bc0>
//<_TtC11lldb_expr_01B: 0x7f85ab451e00>
//<_TtC11lldb_expr_01C: 0x7f85ab509160>

class D {
    @required init() { } 
}

class E : D {
    init() { }
}

class F : D {
    init() { }
}

func Create2<T:D> () -> T {
    return T()
}

println(Create2() as D)
println(Create2() as E)
println(Create2() as F)

//C11lldb_expr_01D (has 0 children)
//C11lldb_expr_01E (has 1 child)
//C11lldb_expr_01F (has 1 child)

不知道为什么@required解决问题.但是this is the reference

required

Apply this attribute to a designated or convenience
initializer of a class to indicate that every subclass must implement
that initializer.

required designated initializers must be implemented explicitly. required convenience initializers can be either implemented explicitly or inherited when the subclass directly implements all of the superclass’s designated initializers (or when the subclass overrides the designated initializers with convenience initializers).

猜你在找的Swift相关文章