我正在尝试向Swift中的泛型类添加一个类型(aka静态)方法。这是代码。
class StateArchive<T> {
class func emptyAllArchives() {
// do something
}
}
// the compiler emits an error: "Argument for generic parameter 'T' could not be inferred"
StateArchive.emptyAllArchives()
我可以通过提供代替T的类型来编译上面的代码:
StateArchive<AnyObject>.emptyAllArchives()
“泛型类型尚不支持的类存储属性”。
有没有人知道如何在泛型类型中创建一个类型方法,让客户端调用此方法而不提供代替T的类型?
答案 0 :(得分:7)
当遇到泛型无法正常工作的问题时,为了帮助理解这个问题,通常会有用,想一想如果用不同的具体类型替换占位符会发生什么。
例如,假设你定义了以下内容(由于你给出的原因,这不会编译,但想象一下):
class C<T> {
static var a: [T] = []
static func addElement(i: T) {
a.append(i)
}
}
真的,当你写class C<T>
时,你不是在写一堂课。您正在为无数可能的类编写蓝图 - C<Int>
,C<String>
,C<AnythingElse>
。
在这种情况下,假设您撰写了C.addElement(1)
- 所以T
将是Int
。然后,你写了C.addElement("one")
。 C.a
现在会包含一个项目,还是两个? a
的类型是什么?
可能最合理的答案是,C<Int>.a
有一个元素,C<String>.a
有一个元素。但这可能会让人感到非常困惑,并且似乎没有用例来证明这种功能的合理性。
通常,静态方法和属性最好很少使用,并且您可能会发现使用非静态成员和方法,结合单例模式(或者甚至可能不是这样)会更好。如果您仍然需要类似静态的函数,那么最好使用通用的自由函数(例如func emptyArchive<T: C>(c: C) { }
)。
答案 1 :(得分:0)
另一个答案在其解释中是正确的,但实际上您可以通过以下方式获得您直觉上期望的行为:
extension StateArchive where T == Any {
static func emptyAllArchives() {
// do something
}
}
// works as expected
StateArchive.emptyAllArchives()