ios - pass - ¿Para qué se usa el "yo" en Swift?
swift selector with arguments (7)
Soy nuevo en Swift y me pregunto para qué se usa el self
y por qué.
Lo he visto en clases y estructuras, pero realmente no las considero esenciales ni necesarias ni siquiera para mencionarlas en mi código. ¿Para qué se usan 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 mis preguntas y siempre tienden a compararlo con this
como en Java, con el que no estoy familiarizado.
En qué situaciones es necesario usarlo
Es necesario usarlo solo cuando el nombre de una variable local eclipsa el nombre de una propiedad.
Sin embargo, como una cuestión de estilo (y legibilidad), siempre lo uso:
Lo uso con nombres de propiedades, porque de lo contrario me pregunto qué es esta variable (ya que no está localmente declarada ni es un parámetro entrante).
Lo uso como el receptor de llamadas de función (método), para diferenciar tales métodos de las funciones locales o de nivel superior.
Antes que nada: buenas respuestas, ejemplos y explicaciones ya publicadas aquí, aunque debo señalar algo:
Palabra reservada: self
in 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 instancia en sí misma.
Y aquí comienza una de las principales diferencias, porque:
- "Cada instancia" en forma rápida (al menos por ahora) es casi todo
- Cuando en Java (por ejemplo) solo puedes usar word
this
dentro de un ámbito de instancia, en swift puedes usarlo casi en todas partes
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, consulte: por qué ''self.self'' compila y ejecuta en forma rápida
La pregunta de OP es acerca de qué es en poco tiempo, así que no aburriré a los lectores con explicaciones sobre lo que es Java o Javascript (pero si algunos lectores lo necesitan, solo escriban un comentario).
El siguiente artículo explica self
en detalles:
Cómo usar correctamente la palabra clave ''self'' en Swift
self
es una propiedad en la instancia que se refiere a sí misma. Se usa para acceder a la clase, la estructura y la instancia de enumeración dentro de los métodos.
Cuando se accede a self en un método de tipo ( static func
o static func
class func
), se refiere al tipo real (en lugar de a una instancia).
Swift permite omitir el self
cuando desea acceder a las propiedades de las instancias.
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. Tenga en cuenta que los parámetros del método tienen prioridad sobre las propiedades de la instancia.
También usará mucho auto cuando cree sus extensiones, por 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 de la var si mismo tiene que usar el func mutante para hacer el cambio en 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 permite cambiar myString1
myString1.replicateMe(3)
println(myString1) // "AbcAbcAbc"
Voy a hablar sobre por qué nos necesitamos.
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 para su Objeto de clase .
Puede crear una imagen de 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.
Eso significa que todas las instancias creadas con la clase comparten el mismo método.
Ahora imaginando que usted es el myMethod
en el objeto Class, y dado que se comparte para todas las instancias, debe tener una forma de saber en qué instancia está trabajando.
Cuando alguien dice instance1.myMethod()
, significa "Hola, myMethod
, haz tu trabajo y instance1
es el objeto en el que estás trabajando".
¿Cómo referencia el objeto que le envió la persona que llama, use self
.
Corrígeme si me equivoco, gracias.
"En la práctica, no necesitas escribir self en tu código muy a menudo. Si no escribe explícitamente uno mismo, Swift asume que se está refiriendo a una propiedad o método de la instancia actual siempre que use una propiedad conocida o nombre de método dentro de un método ".
Extracto de: Apple Inc. "The Swift Programming Language". IBooks. https://itun.es/tw/jEUH0.l
Actualización: 24 de noviembre de 2015
Sí, es lo mismo que en Java y en Objective-C , pero con Swift , solo se requiere cuando llama a una propiedad o método desde un cierre o para diferenciar nombres de propiedad dentro de su código ( por ejemplo, inicializadores). De modo que puede usar casi todos los componentes de su clase de manera segura sin usar uno mismo, a menos que realice una llamada desde un cierre.
"La propiedad propia Cada instancia de un tipo tiene una propiedad implícita llamada
self
, que es exactamente equivalente a la instancia en sí misma. Utiliza la propiedad deself
para referirse a la instancia actual dentro de sus propios métodos de instancia.El método
increment()
en el ejemplo anterior podría haberse escrito así:
func increment() { self.count++ }
En la práctica, no necesita escribir
self
en su código muy a menudo. Si no escribe explícitamenteself
, Swift asume que se está refiriendo a una propiedad o método de la instancia actual cada vez que usa una propiedad conocida o nombre de método dentro de un método. Esta suposición se demuestra mediante el uso decount
(en lugar deself.count
) dentro de los tres métodos de instancia para Counter.La principal excepción a esta regla se produce cuando un nombre de parámetro para un método de instancia tiene el mismo nombre que una propiedad de esa instancia. En esta situación, el nombre del parámetro tiene prioridad y es necesario referirse a la propiedad de una manera más calificada. Utiliza la propiedad
self
para distinguir entre el nombre del parámetro y el nombre de la propiedad.Aquí, desambigua
self
entre un parámetro de método llamadox
y una propiedad de instancia que también se llamax
: "
Extracto de: Apple Inc. "The Swift Programming Language (Swift 2 Prerelease)".
Así es como Ray Wenderlich recomienda el uso de self
en Swift para sus tutoriales:
Uso de uno mismo
Para mayor concisión, evite usar self ya que Swift no requiere que acceda a las propiedades de un objeto ni invoque sus métodos.
Utilice self cuando sea necesario para diferenciar entre nombres de propiedad 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 estas son las recomendaciones de GitHub en self
para sus aplicaciones:
Solo explícitamente se refiere a self
cuando sea necesario
Al acceder a propiedades o métodos en self
, deje la referencia implícita por defecto:
private class History {
var events: [Event]
func rewrite() {
events = []
}
}
Solo incluya la palabra clave explícita cuando lo requiera el idioma, 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()
}
}
}
Justificación: Esto hace que la semántica de captura del self se destaque más en los cierres, y evita la verbosidad en otros lugares.
self es una propiedad en la instancia que se refiere a sí misma. Se usa para acceder a la clase, la estructura y la 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. Tenga en cuenta 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