visual studio microsoft español descargar community swift static-methods

swift - studio - Métodos estáticos de llamada rápida: tipo(de: auto) vs nombre de clase explícito



visual studio windows 7 (2)

Hay dos diferencias principales.

1. El valor del self dentro del método estático.

El metatipo en el que llama al método estático está disponible en el método como self (simplemente se pasa como un parámetro implícito). Por lo tanto, si llama a doIt() en type(of: self) , self será el metatipo dinámico de la instancia. Si lo llamas en Foo , el self será 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

Esta diferencia puede ser realmente importante para los métodos de fábrica, ya que determina el tipo de instancia que crea.

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. El envío del método estático.

( Martin ya ha cubierto esto, pero pensé que lo agregaría para completar ) .

Para class métodos de class que se sobrescriben en las subclases, el valor del metatipo al que llama el método determina a qué implementación llamar.

Si se llama en un metatipo que se conoce en el momento de la compilación (por ejemplo, Foo.doIt() ), Swift puede enviar la llamada de forma estática. Sin embargo, si llama al método en un metatipo que no se conoce hasta el tiempo de ejecución (por ejemplo, type(of: self) ), la llamada al método se enviará dinámicamente a la implementación correcta para el valor de metatype.

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

En swift, una func instancia no puede llamar a una función static/class func sin prefijar la llamada al método con el nombre de la clase. O puedes usar type(of: self) , por ejemplo

class Foo { static func doIt() { } func callIt() { Foo.doIt() // This works type(of: self).doIt() // Or this doIt() // This doesn''t compile (unresolved identifier) } }

Mi pregunta es, ¿cuál es la diferencia aquí? ¿Es solo una cuestión de estilo de codificación, o hay alguna diferencia, por ejemplo, el envío estático o dinámico?

Si es solo un estilo de codificación, ¿cuál es el estilo preferido?


Para un método de class hace una diferencia si el método se invalida en una subclase:

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

Esto también se documenta en "Types" en la Referencia del lenguaje Swift:

Puede usar una expresión de type(of:) con una instancia de un tipo para acceder al tipo de tiempo de ejecución dinámico de la instancia, como un valor, ...

No sé la diferencia de un método static (que es final y no se puede anular en una subclase). Corrección: vea la respuesta de Hamish para ver la diferencia entre los métodos estáticos y de clase.