如何声明一个有类型约束的数组?
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 函数更好的方法!
我要这么声明:
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 函数更好的方法!