如何声明具有类型约束的数组?

时间:2015-01-08 03:31:21

标签: swift

我希望如此声明:

var types:Array<T.Type where T:Cacheable> = []
存储T.self的

。但语法错了。什么是正确的方法?感谢。

为了更清楚,这里简要描述了我想做的事情:

protocol Cacheable {
    class func cacheKey() -> String
}

class User:Cacheable {
    class func cacheKey() -> String {
        return "user"
    }
}

class Post:Cacheable {
    class func cacheKey() -> String {
        return "post"
    }
}

func initTables(type: Cacheable.Type) {
    println(type.cacheKey()) // errors if use @Matt solution
}

func startup() {
    for type:Cacheable.Type in [User.self, Post.self] {
        initTables(type)
    }
}

1 个答案:

答案 0 :(得分:1)

我试过这个似乎有效:

protocol Cacheable {}
struct S1 : Cacheable {}
struct S2 : Cacheable {}

var types : Array<Cacheable.Type> = []

// and this shows that we can actually store types in the array
types.append(S1)
types.append(S2)

如果你试图像types.append(String)那样说错了,编译器会阻止你并抱怨String不符合Cacheable,这正是我们希望它说的......!


编辑好的,所以你已经在你的问题上移动了球门柱。这是一个有趣的新问题,但这是一个完全不同的问题。这里的问题是协议是“存在的元类型”,而不是“元类型”。您无法通过协议以多态方式访问类函数。你必须使用超类。这有效:

class Super {
    class func cacheKey() -> String {
        return "super"
    }
}

class User:Super {
    override class func cacheKey() -> String {
        return "user"
    }
}

class Post:Super {
    override class func cacheKey() -> String {
        return "post"
    }
}

func test() {
    for type : Super.Type in [User.self, Post.self] {
        println(type.cacheKey())
    }
}

所以,如果你没有Post和User的其他超类,给他们一个任意超类Super。如果你有一个Post和User的超类,那么在扩展名中给该类一个类func cacheKey()。无论哪种方式,您现在都拥有一个多态类func cacheKey,这就是您所追求的。


然而,您的真正的问题似乎是第三个问题,即如何获得类的唯一标识符。有可能比使用像这样的类函数更好的方法!