web-dev-qa-db-fra.com

À quoi sert "soi" dans Swift?

Je suis nouveau à Swift et je me demande à quoi sert self et pourquoi.

Je l'ai vu dans les classes et les structures, mais je ne les trouve vraiment ni essentielles ni même nécessaires pour les mentionner dans mon code. À quoi servent-ils et pourquoi? Dans quelles situations faut-il l'utiliser?

J'ai lu beaucoup de questions et de réponses pour cette question, mais aucune d'entre elles ne répond pleinement à mes questions et elles ont toujours tendance à la comparer avec this comme en Java, avec lequel je ne suis pas du tout familier.

34

Vous allez également beaucoup vous utiliser lors de la création de vos extensions, par exemple:

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

maintenant, disons que vous voulez changer le résultat var lui-même.

var z = 3

println(z)  // 3

laisse maintenant le muter

z.squareMe()

println(z)  // 9

// laisse maintenant voir un autre exemple en utilisant des chaînes:

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"

laisse maintenant changer myString1

myString1.replicateMe(3)

println(myString1)         // "AbcAbcAbc"
24
Leo Dabus

Mise à jour: 24 novembre 2015

Oui, c'est la même chose que this dans Java et self dans Objective-C, mais avec Swift, self n'est requis que lorsque vous appelez une propriété ou une méthode à partir d'une clôture ou pour la différencier noms dans votre code (par exemple initialiseurs). Ainsi, vous pouvez utiliser presque tous les composants de votre classe en toute sécurité sans utiliser self, sauf si vous appelez à partir d'une fermeture.

“La propriété self Chaque instance d'un type a une propriété implicite appelé self, qui est exactement équivalent à l'instance elle-même. Vous utilisez la propriété self pour faire référence à l'instance actuelle dans son propres méthodes d'instance.

La méthode increment() dans l'exemple ci-dessus aurait pu être écrite comme ça:

func increment() {
    self.count++
}

En pratique, il n’est pas nécessaire d’écrire self dans votre code très souvent . Si vous n'écrivez pas explicitement self, Swift suppose que vous êtes faisant référence à une propriété ou à une méthode de l'instance actuelle chaque fois que vous utiliser une propriété connue ou un nom de méthode dans une méthode. Cette hypothèse est démontré par l'utilisation de count (plutôt que self.count) dans les trois méthodes d'instance pour Counter.

La principale exception à cette règle se produit lorsqu'un nom de paramètre est attribué à un La méthode d'instance a le même nom qu'une propriété de cette instance. Dans Dans cette situation, le nom du paramètre a la priorité et devient nécessaire de faire référence à la propriété de manière plus qualifiée. Tu utilises la propriété self pour faire la distinction entre le nom du paramètre et le nom de la propriété.

Ici, self ne comprend pas un paramètre de méthode appelé x et une propriété d'instance également appelée x: ”

Extrait de: Apple Inc. «Le langage de programmation Swift (Swift 2 Prerelease).» 


Voici comment Ray Wenderlich recommande l’utilisation de self dans Swift pour leurs tutoriels:

Utilisation de soi

Par souci de concision, évitez d’utiliser self, car Swift ne l’oblige pas à accéder aux propriétés d’un objet ni à appeler ses méthodes.

Utilisez self lorsque nécessaire pour différencier les noms de propriétés et les arguments dans les initialiseurs et lors de la référence à des propriétés dans des expressions de fermeture (comme requis par le compilateur):

class BoardLocation {
  let row: Int, column: Int

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

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

Et voici les recommandations de GitHub sur self pour leurs applications:

Faites explicitement référence à self lorsque cela est nécessaire

Lorsque vous accédez à des propriétés ou des méthodes sur self, laissez la référence à self implicite par défaut:

private class History {
    var events: [Event]

    func rewrite() {
        events = []
    }
}

N'incluez le mot clé explicite que lorsque le langage le requiert (par exemple, dans une fermeture ou en cas de conflit de noms de paramètres):

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

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

Justification: Cela rend la sémantique de capture de soi plus visible dans les fermetures et évite la verbosité ailleurs.

59
David Gomez

Dans quelles situations il faut l'utiliser

Il est nécessaire de ne l'utiliser que lorsque le nom d'une variable locale masque le nom d'une propriété.

Cependant, en ce qui concerne le {style} _ (et la lisibilité), je l’utilise toujours:

  • Je l'utilise avec des noms de propriétés, car sinon je me demande quelle est cette variable (puisqu'elle n'est ni déclarée localement ni un paramètre entrant).

  • Je l'utilise comme récepteur d'appels de fonction (méthode) afin de différencier ces méthodes des fonctions de niveau supérieur ou locales.

16
matt

Je vais parler de la raison pour laquelle nous avons besoin de self.

Quand on définit une classe, comme:

class MyClass {
    func myMethod()
}

Nous créons un objet Class. Oui, la classe est aussi un objet.

Alors, quel que soit le nombre d'instances créées à l'aide de la classe, toutes les instances auront une référence à son objet Class.

Vous pouvez imaginer que toutes les méthodes d'instance définies par la classe se trouvent dans l'objet de classe et qu'il n'y en aura qu'une copie.

enter image description here

Cela signifie que toutes les instances créées à l'aide de la classe partagent la même méthode.

Imaginez maintenant que vous êtes la myMethod dans l'objet de classe et que vous êtes partagé pour toutes les instances, vous devez disposer d'un moyen de déterminer sur quelle instance vous travaillez.

Quand quelqu'un dit instance1.myMethod(), cela signifie "Salut! myMethod, veuillez faire votre travail et instance1 est l'objet sur lequel vous travaillez".

Comment faites-vous référence à l'objet que l'appelant vous a envoyé, utilisez self.

Corrigez-moi si je me trompe, merci.

«En pratique, vous n’avez pas besoin de vous écrire très souvent dans votre code. Si vous ne vous écrivez pas explicitement, Swift suppose que vous faites référence à une propriété ou à une méthode de l'instance actuelle chaque fois que vous utilisez un fichier propriété ou nom de méthode connu dans une méthode. ”

Extrait de: Apple Inc. «Le langage de programmation Swift.» IBooks . https://itun.es/tw/jEUH0.l

10
ylin0x81

Tout d’abord: bonnes réponses, exemples et explications déjà postés ici, même si je dois signaler quelque chose:

Mot réservé: self dans Swift est similaire à thismais ce n'est pas la même chose qu'en Java ou en Javascript.

Comme @Dave Gomez a correctement cité: 

Chaque instance d'un type a une propriété implicite appelée self, qui est exactement équivalente à l'instance elle-même. 

Et voici l'une des principales différences, car:

  1. "Every instance" dans Swift (du moins pour l'instant) est presque Tout
  2. En Java (par exemple), vous ne pouvez utiliser que Word this dans une étendue d'instance, dans Swift, vous pouvez l'utiliser presque Every-where

Voici quelques exemples: 

//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 vous souhaitez en savoir plus, veuillez consulter: Pourquoi «self.self» est compilé et exécuté à Swift

La question OP concerne ce qu’elle est dans Swift, je ne vais donc pas expliquer aux lecteurs ce qu’elle est en Java ou en Javascript (mais si certains lecteurs en ont besoin, écrivez simplement un commentaire).

7
Nikita Kurtin

L'article suivant explique self en détail:

Comment utiliser correctement le mot clé 'self' dans Swift


self est une propriété de l'instance qui fait référence à elle-même. Il est utilisé pour accéder à une instance de classe, de structure et d'énumération au sein de méthodes.

Lorsqu'on accède à self dans une méthode type (static func ou class func), il fait référence au type actuel (plutôt qu'à une instance).

Swift permet d'omettre self lorsque vous souhaitez accéder aux propriétés d'instances.

Lorsqu'un paramètre de méthode porte le même nom que la propriété d'instance, vous devez explicitement utiliser self.myVariable = myVariable pour établir une distinction. Notez que les paramètres de méthode ont une priorité sur les propriétés d’instance. 

3
Dmitri Pavlutin

self est une propriété sur l'instance qui se réfère à elle-même. Il est utilisé pour accéder à une instance de classe, de structure et d'énumération dans les méthodes . Lorsqu'un paramètre de méthode porte le même nom que la propriété d'instance, vous devez explicitement utiliser self.myVariable = myVariable pour établir une distinction. Notez que les paramètres de méthode ont une priorité sur les propriétés d’instance.

    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
akbar khan