Swift 调用静态方法:type(of: self) 与显式类名

2024-04-29

快速地,一个例子func不能打电话static/class func无需在方法调用前添加类名前缀。或者你可以使用type(of: self), e.g

class Foo {
    static func doIt() { }

    func callIt() {
        Foo.doIt() // This works
        type(of: self).doIt() // Or this

        doIt() // This doesn't compile (unresolved identifier)
    }
}

我的问题是,这里有什么区别? 这只是编码风格的问题,还是有一些区别,例如正在进行静态或动态调度?

如果只是编码风格,首选的风格是什么?


有两个主要区别。

1. 价值self静态方法内部

您在方法中可以使用调用静态方法的元类型,如下所示self(它只是作为隐式参数传递)。因此如果你打电话doIt() on type(of: self) https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/postfix-self-expression, self将是dynamic实例的元类型。如果你打电话Foo, selfFoo.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

这个差异可以是really对于工厂方法很重要,因为它决定了您创建的实例的类型。

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. 静态方法的调度

(马丁已经报道过 https://stackoverflow.com/a/42260517/2976878这个,但我想为了完成而添加它。)

For 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swift 调用静态方法:type(of: self) 与显式类名 的相关文章

随机推荐