Что такое " я " используется в Swift?

Я новичок в Swift, и мне интересно, что self используется для и почему.

Я видел это в классах и структурах, но я действительно не считаю их необходимыми или необходимыми даже упоминать их в моем коде. Для чего они используются и почему? В каких ситуациях необходимо его использовать?

Я читал много вопросов и ответов на этот вопрос, но ни один из них полностью отвечает на мои вопросы и они всегда склонны сравнивать его с this как в Java, с которого я совсем не знаю.

7 ответов


вы также будете использовать self много при создании расширений, например:

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

теперь давайте скажем, что вы хотите изменить сам результат var вы должны использовать мутирующий func, чтобы изменить себя

var z = 3

println(z)  // 3

теперь давайте мутировать его

z.squareMe()

println(z)  // 9

/ / теперь давайте посмотрим другой пример использования строк:

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"

теперь давайте изменим myString1

myString1.replicateMe(3)

println(myString1)         // "AbcAbcAbc"

Обновление: 24 Ноября 2015 Года!--24-->

Да это то же самое, что this на Java и self на С, но с Свифт, self требуется только при вызове свойства или метода из закрытия или для различения имен свойств внутри кода (например инициализаторы). Таким образом, вы можете безопасно использовать почти все компоненты класса, не используя self, если вы не звоните из закрытие.

" свойство self каждый экземпляр типа имеет неявное свойство называется self, что в точности эквивалентно самому экземпляру. Вы используйте self свойство для ссылки на текущий экземпляр в его собственные методы экземпляра.

на increment() метод в приведенном выше примере можно было бы написать вот так:

func increment() {
    self.count++
}

на практике, вам не надо писать self в коде очень часто. Если вы не пишите явно self, Swift предполагает, что вы ссылка на свойство или метод текущего экземпляра всякий раз, когда вы используйте известное свойство или имя метода в методе. Это предположение демонстрирует использование count (а не self.count) внутри трех методов экземпляра для Counter.

основное исключение из этого правила возникает, когда имя параметра для метод экземпляра имеет то же имя, что и свойство этого экземпляра. В эта ситуация, имя параметра имеет приоритет и становится необходимо обратиться к собственности более квалифицированным способом. Вы используете the self свойство для различения имени параметра и имя свойства.

здесь self различать между параметром метод, называемый x и свойство экземпляра, которое также называется x:"

Выдержка Из: Apple Inc. "Язык Программирования Swift (Предварительная Версия Swift 2)."


это как Рэй Вендерлих рекомендует использовать self в Swift для их руководства:

использование Self

для краткости избегайте использования self, поскольку Swift не требует доступа к свойствам объекта или вызова его методов.

используйте self при необходимости для различения имен свойств и аргументов в инициализаторах и при ссылке на свойства в выражениях закрытия (как требуется составитель):

class BoardLocation {
  let row: Int, column: Int

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

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

и GitHub рекомендации по self для их применения:

только явно ссылаться на self при необходимости

при доступе к свойствам или методам в self, оставить ссылку на self подразумевается по умолчанию:

private class History {
    var events: [Event]

    func rewrite() {
        events = []
    }
}

включить ключевое слово explicit только тогда, когда это требуется языком-например, в закрытии или когда конфликт имен параметров:

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

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

обоснование: это делает семантику захвата себя более заметной в закрытиях и избегает многословия в другом месте.


в каких ситуациях нужно использовать

Это необходимые использовать его только тогда, когда имя локальной переменной затмевает имя свойства.

однако, как вопрос стиль (и читаемость), я всегда использую его:

  • Я использую его с именами свойств, потому что в противном случае мне интересно, что это за переменная (поскольку она не объявлена локально и не является входящей параметр.)

  • Я использую его как приемник вызовов функций (методов), чтобы отличить такие методы от функций верхнего уровня или локальных функций.


Я собираюсь поговорить о том, зачем нужны self.

когда мы определяем класс, как:

class MyClass {
    func myMethod()
}

мы создаем Класс Объекта. Да, класс-это тоже объект.

тогда независимо от того, сколько экземпляров создается с помощью класса, все экземпляры будут иметь ссылки на его Класс Объекта.

вы можете представить, что все методы экземпляра, определенные классом, находятся в объекте класса, и будет только один экземпляр.

enter image description here

это означает, что все экземпляры, созданные с помощью класса, используют один и тот же метод.

теперь представьте, что вы myMethod в объекте Class и поскольку вы разделяетесь для всех экземпляров, у вас должен быть способ определить, над каким экземпляром вы работаете.

когда кто-то говорит instance1.myMethod(), это означает "Привет! myMethod, пожалуйста, сделайте свою работу и instance1 это объект, над которым вы работаете".

как вы ссылка на объект, который вызывающий абонент отправил вам, используйте self.

поправьте меня, если я ошибаюсь, спасибо.

"на практике вам не нужно писать себя в своем коде очень часто. Если вы явно не пишете self, Swift предполагает, что вы ссылаетесь свойству или методу текущего экземпляра при каждом использовании известное свойство или имя метода в методе."

Выдержка Из: Apple Inc. "Язык Программирования Swift."в iBooks. https://itun.es/tw/jEUH0.l


прежде всего: хорошие ответы, примеры и объяснения уже размещены здесь, хотя я должен кое-что указать:

зарезервированное слово: self в swift похож на this но это не то же самое, что в Java или Javascript.

Как правильно процитировал @Dave Gomez:

каждый экземпляр типа имеет неявное свойство self, которое точно эквивалентно самому экземпляру.

и здесь начинается одно из главных отличий, потому что:

  1. "каждый экземпляр" в swift (по крайней мере, пока) почти все
  2. когда в Java (например) вы можете использовать только word this внутри области экземпляра, в swift вы можете использовать его почти везде

вот несколько примеров:

//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)

если вы хотите прочитать больше, пожалуйста, смотрите:почему "я".я компиляции и запуска в swift

вопрос OP о том, что это такое в swift, поэтому я не буду утомлять читателей объяснениями, что это такое на Java или Javascript (но если некоторым читателям это нужно, просто напишите комментарий).


в следующей статье объясняется self подробнее:

Как правильно использовать ключевое слово "self" в Swift


self - свойство экземпляра, которое ссылается на себя. Он используется для доступа к экземпляру класса, структуры и перечисления в методах.

когда self доступен в методе типа (static func или class func), это относится к фактическому типу (а не к экземпляру).

Swift позволяет опустить self когда вы хотите получить доступ к свойствам экземпляров.

когда параметр метода имеет то же имя, что и свойство экземпляра, вы должны явно использовать self.myVariable = myVariable чтобы сделать различие. Обратите внимание, что параметры метода имеют приоритет над свойствами экземпляра.


self-это свойство экземпляра, которое ссылается на себя. Он используется для доступа к экземпляру класса, структуры и перечисления в методах. Если параметр метода имеет то же имя, что и свойство экземпляра, необходимо явно использовать self.переменная = переменная, чтобы сделать различие. Обратите внимание, что параметры метода имеют приоритет над свойствами экземпляра.

    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