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

How to declare an array with type constraints?

我要这么声明:

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)
    }
}

我试过了,似乎有效:

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,这正是我们希望它说的......!


编辑 好的,您已经移动了问题的目标。这是一个有趣的新问题,但它是一个完全不同的问题。这里的问题是协议是 "existential metatype",而不是 "metatype"。您不能通过协议以多态方式访问 class 函数。您必须改用 superclass 。这有效:

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())
    }
}

所以,如果你没有其他 superclass 给 Post 和 User,给他们一个任意的 superclass Super。如果你 do 有一个 superclass 用于 Post 和 User,然后给那个 class 一个 class func cacheKey()在扩展中。无论哪种方式,你现在都有一个多态的 class func cacheKey 这就是你所追求的。


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