混合
我有一个 mixin,它打印将类名作为 String
分配给实例变量。
import Foundation
protocol Recyclable {
static var name: String { get }
}
extension Recyclable {
static var name: String {
return String(describing: Self.self)
}
}
有两个类实现了mixin:
class One: NSObject, Recyclable { }
class Two: NSObject, Recyclable { }
所以如果我想打印类名,我可以
One.self.name // "One"
这非常有效。现在让我们更深入一些。
打印多个给定类的通用函数
将其放入函数中以打印所有给定类的名称。它必须是通用的,因为它可以接受任何符合 Recyclable protocol
的类。
func printAllNames<T: NSObject>(_ things: T.Type...) where T: Recyclable {
for thing in things {
print(thing.name)
}
}
如果我只将它用于一个类,它会按预期工作。
printAllNames(One.self) // "One"
但是当与多个一起使用时,它会出错
printAllNames(One.self, Two.self)
Playground execution failed: error: GenericMixins.playground:20:1: error: generic parameter 'T' could not be inferred printAllNames(One.self, Two.self)
关于可能发生的事情的任何提示?
Playground :https://www.dropbox.com/sh/q0b5b3oo0luj471/AABSG2QEOIj_SBsvtv7cEv-Ka?dl=0
最佳答案
问题,如@dirtydanee says , 是通用占位符 T
表示要在函数的调用点满足的单个 类型。因此可变参数 T.Type...
为相同类型表达一系列元类型 T
.
解决方案就是拥有一个 Recyclable.Type...
参数,表示符合Recyclable
的任何类型的一系列元类型:
func printAllNames(_ things: Recyclable.Type...) {
for thing in things {
print(thing.name)
}
}
printAllNames(One.self, Two.self)
这不表示 NSObject
对 T
的约束你有,但你没有在函数本身的实现中使用该约束。
如果这只是一个简化的示例,而您实际上想要为任何类型都继承自 NSObject
的任何类型表达一系列元类型。并符合 Recyclable
– 你目前无法在 Swift 3 中表达这一点。
但是在 Swift 4 中,我们可以用 a class existential 来表达它的 NSObject & Recyclable
:
func printAllNames(_ things: (NSObject & Recyclable).Type...) {
for thing in things {
print(thing.name)
}
}
关于swift - 具有多个具有 mixin 的类的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44426828/