Ori*_*rds 26 static-methods swift
在swift中,如果没有使用类名称为方法调用添加前缀,则实例func不能调用a 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)
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,这有什么区别?它只是编码风格的问题,还是存在一些差异,例如静态或动态调度?
如果它只是编码风格,那么首选的风格是什么?
Ham*_*ish 31
主要有两个不同之处.
self静态方法内部的值您在方法中可以使用您调用静态方法的元类型self(它只是作为隐式参数传递).因此,如果你打电话doIt()的type(of: self),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
Run Code Online (Sandbox Code Playgroud)
这种差异对于工厂方法非常重要,因为它决定了您创建的实例的类型.
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
Run Code Online (Sandbox Code Playgroud)
(马丁已经介绍了这一点,但我想我会为了完成而添加它.)
对于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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12346 次 |
| 最近记录: |