加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

泛型与Swift中的T型通话

发布时间:2020-12-14 05:43:03 所属栏目:百科 来源:网络整理
导读:在我的应用程序中,我想创建一个通用的方法,它创建一个给定类型T的对象依赖的数组. 我创建了以下功能: func getArrayT : ROJSONObject(key:String) - T[] { var elements = T[]() for jsonValue in getValue(key).array! { var element = T() element.jsonDa
在我的应用程序中,我想创建一个通用的方法,它创建一个给定类型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).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读