微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

泛型与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).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐