如何在 Swift 4.1 中迭代一个类型数组?
How to iterate over an array of types in Swift 4.1?
我在 上使用 Xcode 9.4.1 和 Swift 4.1 iOS11.4.1.
我有一些协议,例如:
protocol Bla {
// some stuff
}
protocol Gorp {
// some other stuff
}
我有一些符合这两种协议的结构,如下所示:
typealias MyType = Bla & Gorp
struct Hello: MyType {
var ID: Int
var name: String
}
struct Goodbye: MyType {
var percentage: Double
var hairbrush: String
}
然后我得到一个带有参数的函数 theType,它符合 Bla 和 Gorp。在这个例子中,我只是打印一个描述——像这样:
func doSomething<T: MyType>(_ theType: T.Type) {
// some stuff
print("Got called... \(theType)")
}
而且,我可以调用此函数传递两种结构类型(Hello 和 Goodbye),如下所示:
doSomething(Hello.self)
doSomething(Goodbye.self)
效果很好,我得到了预期的以下输出:
Got called... Hello
Got called... Goodbye
但是,我真正想做的是迭代其中的一堆,而不是单独调用它们。
这种方式给我一个错误“注意:需要一个类型为'(T.Type)'”的参数列表:
for thingy in [Hello.self, Goodbye.self] {
doSomething(thingy)
}
如果我添加一个 as! [MyType.Type] 或 as! [MyType],我得到同样的错误。我也试过这个:
for thingy in [Hello.self as MyType.Type, Goodbye.self as MyType.Type] {
doSomething(thingy)
}
与其他错误相同。
我也尝试过不使用 typealias。
如果我开始输入,自动完成会说 doSomething 需要一个类型为 (Bla & Gorp).Protocol 的参数。所以,我也试过这个:
for thingy in [Hello.self, Goodbye.self] as! [(Bla & Gorp).Protocol] {
doSomething(thingy)
}
在这种情况下,我收到消息:
In argument type '(Bla & Gorp).Protocol', 'Bla & Gorp' does not conform to expected type 'Bla'
也尝试过这种方法,但出现错误,“无法使用类型为‘(MyType.Type)’的参数列表调用'doSomething' ":
struct AnyBlaGorp {
let blaGorp: MyType.Type
init<T: MyType>(_ theType: T.Type) {
self.blaGorp = theType
}
}
for thingy in [AnyBlaGorp(Hello.self), AnyBlaGorp(Goodbye.self)] {
doSomething(thingy.blaGorp)
}
如能指出神奇的正确语法,将不胜感激。 :)
您可以使 doSomething
方法成为非通用方法并接受 MyType.Type
。如果您的协议没有 Self
或关联类型,您只能这样做。
func doSomething(_ theType: MyType.Type) {
// some stuff
print("Got called... \(theType)")
}
接下来,您将数组转换为 [MyType.Type]
:
for thingy in [Hello.self, Goodbye.self] as [MyType.Type] {
doSomething(thingy)
}
这利用了这样一个事实,即如果 A
继承 from/conforms 到 B
,A.self
可以转换为类型 B.Type
。
我在 上使用 Xcode 9.4.1 和 Swift 4.1 iOS11.4.1.
我有一些协议,例如:
protocol Bla {
// some stuff
}
protocol Gorp {
// some other stuff
}
我有一些符合这两种协议的结构,如下所示:
typealias MyType = Bla & Gorp
struct Hello: MyType {
var ID: Int
var name: String
}
struct Goodbye: MyType {
var percentage: Double
var hairbrush: String
}
然后我得到一个带有参数的函数 theType,它符合 Bla 和 Gorp。在这个例子中,我只是打印一个描述——像这样:
func doSomething<T: MyType>(_ theType: T.Type) {
// some stuff
print("Got called... \(theType)")
}
而且,我可以调用此函数传递两种结构类型(Hello 和 Goodbye),如下所示:
doSomething(Hello.self)
doSomething(Goodbye.self)
效果很好,我得到了预期的以下输出:
Got called... Hello
Got called... Goodbye
但是,我真正想做的是迭代其中的一堆,而不是单独调用它们。
这种方式给我一个错误“注意:需要一个类型为'(T.Type)'”的参数列表:
for thingy in [Hello.self, Goodbye.self] {
doSomething(thingy)
}
如果我添加一个 as! [MyType.Type] 或 as! [MyType],我得到同样的错误。我也试过这个:
for thingy in [Hello.self as MyType.Type, Goodbye.self as MyType.Type] {
doSomething(thingy)
}
与其他错误相同。
我也尝试过不使用 typealias。
如果我开始输入,自动完成会说 doSomething 需要一个类型为 (Bla & Gorp).Protocol 的参数。所以,我也试过这个:
for thingy in [Hello.self, Goodbye.self] as! [(Bla & Gorp).Protocol] {
doSomething(thingy)
}
在这种情况下,我收到消息:
In argument type '(Bla & Gorp).Protocol', 'Bla & Gorp' does not conform to expected type 'Bla'
也尝试过这种方法,但出现错误,“无法使用类型为‘(MyType.Type)’的参数列表调用'doSomething' ":
struct AnyBlaGorp {
let blaGorp: MyType.Type
init<T: MyType>(_ theType: T.Type) {
self.blaGorp = theType
}
}
for thingy in [AnyBlaGorp(Hello.self), AnyBlaGorp(Goodbye.self)] {
doSomething(thingy.blaGorp)
}
如能指出神奇的正确语法,将不胜感激。 :)
您可以使 doSomething
方法成为非通用方法并接受 MyType.Type
。如果您的协议没有 Self
或关联类型,您只能这样做。
func doSomething(_ theType: MyType.Type) {
// some stuff
print("Got called... \(theType)")
}
接下来,您将数组转换为 [MyType.Type]
:
for thingy in [Hello.self, Goodbye.self] as [MyType.Type] {
doSomething(thingy)
}
这利用了这样一个事实,即如果 A
继承 from/conforms 到 B
,A.self
可以转换为类型 B.Type
。