¿Para qué se utiliza "self" en Swift?


Soy nuevo en Swift y me pregunto para qué se usa self y por qué.

Lo he visto en clases y estructuras, pero realmente no las encuentro esenciales ni necesarias para mencionarlas en mi código. ¿Para qué se utilizan y por qué? ¿En qué situaciones es necesario usarlo?

He estado leyendo muchas preguntas y respuestas para esta pregunta, pero ninguna de ellas responde completamente a mis preguntas y siempre tienden a compararlo con this como en Java, con lo que no estoy familiar en absoluto.

Author: Richard Slater, 2014-11-10

7 answers

También usarás self mucho al crear tus extensiones, ejemplo:

extension Int {
    func square() -> Int {
        return self * self
    }

    // note: when adding mutating in front of it we don't need to specify the return type
    // and instead of "return " whatever
    // we have to use "self = " whatever

    mutating func squareMe() {
        self = self * self
    }
}
let x = 3
let y = x.square()  
println(x)         // 3
printlx(y)         // 9

Ahora digamos que desea cambiar el resultado var en sí tienes que usar el func mutante para hacer el cambio por sí mismo

var z = 3

println(z)  // 3

Ahora vamos a mutarlo

z.squareMe()

println(z)  // 9

/ / ahora veamos otro ejemplo usando cadenas:

extension String {
    func x(times:Int) -> String {
        var result = ""
        if times > 0 {
            for index in 1...times{
                result += self
            }
            return result
        }
        return ""
    }

    // note: when adding mutating in front of it we don't need to specify the return type
    // and instead of "return " whatever
    // we have to use "self = " whatever

    mutating func replicateMe(times:Int){
        if times > 1 {
            let myString = self
            for index in 1...times-1{
                self = self + myString
            }
        } else {
            if times != 1 {
                self = ""
            }
        }
    } 
}


var myString1 = "Abc"
let myString2 = myString1.x(2)

println(myString1)         // "Abc"
println(myString2)         // "AbcAbc"

Ahora vamos a cambiar myString1

myString1.replicateMe(3)

println(myString1)         // "AbcAbcAbc"
 23
Author: Leo Dabus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-10 04:48:35

Actualización: Noviembre 24, 2015

Sí, es lo mismo que this en Java y self en Objective-C, pero con Swift, self solo se requiere cuando llama a una propiedad o método desde un cierre o para diferenciar los nombres de propiedades dentro de su código (por ejemplo, inicializadores). Por lo tanto, puede usar casi todos los componentes de su clase de forma segura sin usar self a menos que esté haciendo la llamada desde un cierre.

" La propiedad de uno mismo Cada instancia de un tipo tiene una propiedad implícita llamado self, que es exactamente equivalente a la instancia en sí. Usted use la propiedad self para referirse a la instancia actual dentro de su métodos de instancia propios.

El método increment() en el ejemplo anterior podría haber sido escrito así:

func increment() {
    self.count++
}

En la práctica, no es necesario escribir self en su código muy a menudo. Si no escribe explícitamente self, Swift asume que es refiriéndose a una propiedad o método de la instancia actual cada vez que utilice un nombre de propiedad o método conocido dentro de un método. Esta suposición se demuestra por el uso de count (en lugar de self.count) dentro de los tres métodos de instancia para Contador.

La excepción principal a esta regla ocurre cuando un nombre de parámetro instance method tiene el mismo nombre que una propiedad de esa instancia. En esta situación, el nombre del parámetro tiene prioridad, y se convierte en necesario para referirse a la propiedad en un más camino calificado. Usted usa la propiedad self para distinguir entre el nombre del parámetro y nombre de la propiedad.

Aquí, self permite desambiguar entre un parámetro de método llamado x y una propiedad de instancia que también se llama x:"

Extracto De: Apple Inc. "The Swift Programming Language (Swift 2 Prerelease)."


Así es como Ray Wenderlich recomienda el uso de self en Swift para su tutoriales:

Uso de Sí mismo

Para ser conciso, evite usar self ya que Swift no lo requiere para acceder a las propiedades de un objeto o invocar sus métodos.

Use self cuando sea necesario para diferenciar entre nombres de propiedades y argumentos en inicializadores, y cuando haga referencia a propiedades en expresiones de cierre (según lo requiera el compilador):

class BoardLocation {
  let row: Int, column: Int

  init(row: Int, column: Int) {
    self.row = row
    self.column = column

    let closure = {
      println(self.row)
    }
  }
}

Y estos son GitHub's recommendations on self for their aplicaciones:

Solo referirse explícitamente a self cuando sea necesario

Al acceder a propiedades o métodos en self, deje la referencia a self implícita por defecto:

private class History {
    var events: [Event]

    func rewrite() {
        events = []
    }
}

Solo incluya la palabra clave explícita cuando el lenguaje lo requiera, por ejemplo, en un cierre, o cuando los nombres de los parámetros entren en conflicto:

extension History {
    init(events: [Event]) {
        self.events = events
    }

    var whenVictorious: () -> () {
        return {
            self.rewrite()
        }
    }
}

Rationale: Esto hace que la semántica de captura del yo se destaque más en los cierres, y evita la verbosidad en otros lugares.

 57
Author: David Gomez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-24 15:52:27

En qué situaciones es necesario usarlo

Es necesario utilizarla solo cuando el nombre de una variable local eclipsa el nombre de una propiedad.

Sin embargo, como cuestión de estilo (y legibilidad), siempre lo uso:

  • Lo uso con nombres de propiedad, porque de lo contrario me pregunto qué es esta variable (ya que no se declara localmente ni es un parámetro entrante).

  • Lo uso como el receptor de llamadas de función (método), con el fin de diferenciar dichos métodos de las funciones de nivel superior o locales.

 14
Author: matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-10 01:22:45

Voy a hablar de por qué necesitamos self.

Cuando definimos una clase, como:

class MyClass {
    func myMethod()
}

Estamos creando un Objeto de Clase . Sí, la clase también es un objeto.

Entonces no importa cuántas instancias se creen usando la clase, todas las instancias tendrán puntos de referencia a su Objeto de Clase .

Puede imaginar que todos los métodos de instancia definidos por la Clase están en el Objeto de Clase, y solo habrá una copia de ellos.

introduzca la descripción de la imagen aquí

Eso significa que todas las instancias creadas usando la Clase comparten el mismo método.

Ahora imagine que usted es el myMethod en el Objeto de Clase, y como se comparte para todas las instancias, debe tener una manera de saber en qué instancia está trabajando.

Cuando alguien dice instance1.myMethod(), significa " ¡Hola! myMethod, por favor haga su trabajo y instance1 es el objeto en el que está trabajando".

¿Cómo se hace referencia al objeto que la persona que llama le envió, utilizar self.

Corrígeme si me equivoco, gracias.

"En la práctica, no es necesario escribir uno mismo en su código muy a menudo. Si no escribes explícitamente self, Swift asume que te estás refiriendo a una propiedad o método de la instancia actual cada vez que utilice un nombre de propiedad o método conocido dentro de un método."

Extracto De: Apple Inc. "The Swift Programming Language."iBooks. https://itun.es/tw/jEUH0.l

 9
Author: ylin0x81,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-12 07:57:11

En primer lugar: Buenas respuestas, ejemplos y explicaciones ya publicadas aquí, aunque debo señalar algo:

Palabra reservada: self en swift es similar a this pero no es lo mismo que en Java o Javascript.

Como @ Dave Gomez citó correctamente:

Cada instancia de un tipo tiene una propiedad implícita llamada self, que es exactamente equivalente a la propia instancia.

Y aquí comienza una de las principales diferencias, porque:

  1. "Cada instancia" en swift (al menos por ahora) es casi Todo
  2. Cuando en Java (por ejemplo) solo se puede usar word this dentro de un ámbito de instancia, en swift se puede usar casi Cada-donde

Aquí algunos ejemplos:

//Example 1:
var x="foo"
x.self="bar".self//compiles and run

//Example 2:
print.self(x);//compiles and run

//Example 3:
func myOther(self otherSelf:Person){}
myOther(self: personObject);//compiles and run

//Example 4:
class Foo{
      var bar=""
      init(){
          self.addSome()//this would be the same in Java
      }
      func addSome(){
          //But definitely not this:
          self.self.bar.self.self="some".self.self
      }
}
//Guess what - also compiles and run...
let f=Foo()
print(f.bar)

Si desea leer más, por favor vea : Por qué 'self.self ' compila y ejecuta en swift

La pregunta de OP es sobre qué es en swift, así que no aburriré lectores con explicaciones de lo que es en Java o Javascript (Pero si algunos lectores lo necesitan simplemente escriba un comentario).

 6
Author: Nikita Kurtin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:09:59

El siguiente artículo explica self en detalle:

Cómo usar correctamente la palabra clave 'self' en Swift


self es una propiedad en la instancia que se refiere a sí misma. Se utiliza para acceder a clase, estructura e instancia de enumeración dentro de los métodos.

Cuando se accede a self en un método de tipo (static func o class func), se refiere al tipo real (en lugar de una instancia).

Swift permite omitir self cuando se desea acceder a instancias propiedad.

Cuando un parámetro de método tiene el mismo nombre que la propiedad de instancia, debe usar explícitamente self.myVariable = myVariable para hacer una distinción. Observe que los parámetros del método tienen prioridad sobre las propiedades de la instancia.

 3
Author: Dmitri Pavlutin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-14 07:42:33

Self es una propiedad en la instancia que se refiere a sí mismo. Se utiliza para acceder a clase, estructura e instancia de enumeración dentro de los métodos. Cuando un parámetro de método tiene el mismo nombre que la propiedad de instancia, debe usar explícitamente self.myVariable = myVariable para hacer una distinción. Observe que los parámetros del método tienen prioridad sobre las propiedades de la instancia.

    struct Weather {
let windSpeed: Int
  let chanceOfRain: Int
  init(windSpeed: Int, chanceOfRain: Int) {
    self.windSpeed = windSpeed
    self.chanceOfRain = chanceOfRain
  }

  func isDayForWalk() -> Bool {
    let comfortableWindSpeed = 5
    let acceptableChanceOfRain = 30
    return self.windSpeed <= comfortableWindSpeed
      && self.chanceOfRain <= acceptableChanceOfRain
  }

}
// A nice day for a walk
let niceWeather = Weather(windSpeed: 4, chanceOfRain: 25)  
print(niceWeather.isDayForWalk()) // => true
 0
Author: akbar khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-05 07:04:56