Swift调用静态方法:类型(of:self)与显式类名
在swift中,实例Swift调用静态方法:类型(of:self)与显式类名,swift,static-methods,Swift,Static Methods,在swift中,实例func不能调用static/class func,除非在方法调用前加上类名。或者您可以使用类型(of:self),例如 class Foo { static func doIt() { } func callIt() { Foo.doIt() // This works type(of: self).doIt() // Or this doIt() // This doesn't compile (unre
func
不能调用static/class func
,除非在方法调用前加上类名。或者您可以使用类型(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)
}
}
我的问题是,这里有什么区别?
这只是编码风格的问题,还是存在一些差异,例如静态或动态调度
如果只是编码样式,那么首选的样式是什么?对于
类
方法,如果方法是
在子类中重写:
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语言参考中:
您可以将类型(of:)
表达式与类型的实例一起使用,以访问该实例的动态运行时类型作为值
我不知道静态
方法(即最终
并且不能在子类中重写)。
更正:请参阅以了解差异
在静态方法和类方法中。有两个主要区别 1.静态方法中的
self
值
调用静态方法的元类型在方法中可用作self
(它只是作为隐式参数传递)。因此,如果调用doIt()
on,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
2.静态法的调度
(这个,但我想我会为了完成而添加它。)
对于在子类中重写的class
方法,调用该方法的元类型的值确定要调用的实现
如果对编译时已知的元类型调用(例如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
我不相信有任何动态调度。我们不在Objective-C世界中,因为没有
@objc
、动态
、或NSObject
继承。@JAL实际上在引擎盖下(至少当包含Obj-C运行时时时是这样)。“纯”Swift也有动态调度功能(想想协议)–这不仅仅是一个Obj-C功能。@Hamish我知道Swift类继承自SwiftObject,但同样适用于开源运行时(不包括协议)?@JAL Yeah,我刚想编辑我的评论,注意到–我没有详细研究开源运行时,但我不相信Swift类是基于Obj-C类的,因为没有Obj-C运行时。请按照苹果的建议来思考这个问题:static
和class
方法的区别在于方法内部的self
的值——请看我的答案:)@Hamish:是的,这是一个很好的观点,我没有想到这一点。