在swift中,实例func
无法调用static/class func
,而无需使用类名为方法调用添加前缀。或者您可以使用type(of: self)
,例如
class Foo {
static func doIt() { }
func callIt() {
Foo.doIt() // This works
type(of: self).doIt() // Or this
doIt() // This doesn't compile (unresolved identifier)
}
}
我的问题是,这里的区别是什么? 这仅仅是编码风格的问题,还是存在一些差异,例如:静态或动态调度正在进行?
如果它只是编码风格,那么首选风格是什么?
答案 0 :(得分:27)
有两个主要区别。
self
的值
您在方法中可以使用调用静态方法的元类型self
(它只是作为隐式参数传递)。因此,如果您在type(of: self)
上致电doIt()
,self
将成为该实例的动态元类型。如果您在Foo
上致电,self
将为Foo.self
。
class Foo {
static func doIt() {
print("hey I'm of type \(self)")
}
func callDoItOnDynamicType() {
type(of: self).doIt() // call on the dynamic metatype of the instance.
}
func classDoItOnFoo() {
Foo.doIt() // call on the metatype Foo.self.
}
}
class Bar : Foo {}
let f: Foo = Bar()
f.callDoItOnDynamicType() // hey I'm of type Bar
f.classDoItOnFoo() // hey I'm of type Foo
对于工厂方法,这种差异可能非常,因为它决定了您创建的实例的类型。
class Foo {
required init() {}
static func create() -> Self {
return self.init()
}
func createDynamic() -> Foo {
return type(of: self).create()
}
func createFoo() -> Foo {
return Foo.create()
}
}
class Bar : Foo {}
let f: Foo = Bar()
print(f.createDynamic()) // Bar
print(f.createFoo()) // Foo
( Martin has already covered这个,但我想我会为了完成而添加它。)
对于在子类中重写的class
方法,调用方法on的元类型的值确定要调用的实现。
如果在编译时已知的元类型(例如Foo.doIt()
)上调用,则Swift能够静态调度该调用。但是,如果在运行时已知的元类型上调用方法(例如type(of: self)
),则方法调用将动态分派给元类型值的正确实现
class Foo {
class func doIt() {
print("Foo's doIt")
}
func callDoItOnDynamicType() {
type(of: self).doIt() // the call to doIt() will be dynamically dispatched.
}
func classDoItOnFoo() {
Foo.doIt() // will be statically dispatched.
}
}
class Bar : Foo {
override class func doIt() {
print("Bar's doIt")
}
}
let f: Foo = Bar()
f.callDoItOnDynamicType() // Bar's doIt
f.classDoItOnFoo() // Foo's doIt
答案 1 :(得分:4)
对于class
方法,如果方法是,则会有所不同
在子类中重写:
class Foo {
class func doIt() {
print("Foo doit")
}
func callViaClassname() {
Foo.doIt()
}
func callViaTypeOf() {
type(of: self).doIt()
}
}
class Bar: Foo {
override class func doIt() {
print("Bar doit")
}
}
Bar().callViaClassname() // Foo doit
Bar().callViaTypeOf() // Bar doit
Swift语言参考中的"Types"中也记录了这一点:
您可以使用
type(of:)
表达式和类型实例来访问该实例的动态,运行时类型作为值,...
我不知道
更正:有关差异,请参阅Hamish's answer
在静态和类方法中。static
方法的区别(final
并且不能在子类中重写。