我有一个打印的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执行失败:错误:GenericMixins.playground:20:1: 错误:无法推断泛型参数“T” printAllNames(One.self,Two.self)
有关可能发生的事情的任何提示?
游乐场:https://www.dropbox.com/sh/q0b5b3oo0luj471/AABSG2QEOIj_SBsvtv7cEv-Ka?dl=0
答案 0 :(得分:1)
问题,如@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
继承并符合NSObject & Recyclable
的任何类型表达一系列元类型 - 您目前无法在Swift 3中表达这一点。
但是在Swift 4中,我们可以<{3}} func printAllNames(_ things: (NSObject & Recyclable).Type...) {
for thing in things {
print(thing.name)
}
}
来表达这一点:
request()->only('args')
答案 1 :(得分:0)
我最终搞清楚了。正确的方法是让函数接受任何东西,然后检查被接受的内容是否符合协议。
该功能应该是
printAllNames(One.self, Two.self)
然后它按预期工作
main
一
两个
更新了游乐场:https://www.dropbox.com/sh/9sjboo3lfu83662/AAC9CKn_dU_wrihCvKUfujQ7a?dl=0