What is “self” used for in Swift?

无人久伴 提交于 2019-11-26 17:40:22

You will also use self a lot when creating your extensions, example:

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

now lets say you want to change the var result itself you have to use the mutating func to make change itself

var z = 3

println(z)  // 3

now lets mutate it

z.squareMe()

println(z)  // 9

// now lets see another example using strings :

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"

now lets change myString1

myString1.replicateMe(3)

println(myString1)         // "AbcAbcAbc"

Update: November 24, 2015

Yes it is the same as this in Java and self in Objective-C, but with Swift, self is only require when you call a property or method from a closure or to differentiate property names inside your code (e.g. initializers). So you can use almost all of your class components safely without using self unless you are making the call from a closure.

“The self Property Every instance of a type has an implicit property called self, which is exactly equivalent to the instance itself. You use the self property to refer to the current instance within its own instance methods.

The increment() method in the example above could have been written like this:

func increment() {
    self.count++
}

In practice, you don’t need to write self in your code very often. If you don’t explicitly write self, Swift assumes that you are referring to a property or method of the current instance whenever you use a known property or method name within a method. This assumption is demonstrated by the use of count (rather than self.count) inside the three instance methods for Counter.

The main exception to this rule occurs when a parameter name for an instance method has the same name as a property of that instance. In this situation, the parameter name takes precedence, and it becomes necessary to refer to the property in a more qualified way. You use the self property to distinguish between the parameter name and the property name.

Here, self disambiguates between a method parameter called x and an instance property that is also called x:”

Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2 Prerelease).”


This is how Ray Wenderlich recommends the use of self in Swift for their tutorials:

Use of Self

For conciseness, avoid using self since Swift does not require it to access an object's properties or invoke its methods.

Use self when required to differentiate between property names and arguments in initializers, and when referencing properties in closure expressions (as required by the compiler):

class BoardLocation {
  let row: Int, column: Int

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

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

And this are GitHub's recommendations on self for their applications:

Only explicitly refer to self when required

When accessing properties or methods on self, leave the reference to self implicit by default:

private class History {
    var events: [Event]

    func rewrite() {
        events = []
    }
}

Only include the explicit keyword when required by the language—for example, in a closure, or when parameter names conflict:

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

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

Rationale: This makes the capturing semantics of self stand out more in closures, and avoids verbosity elsewhere.

In what situations it's necessary to use it

It is necessary to use it only when the name of a local variable overshadows the name of a property.

However, as a matter of style (and readability), I always use it:

  • I use it with property names, because otherwise I am left wondering what this variable is (since it is neither locally declared nor an incoming parameter).

  • I use it as the receiver of function (method) calls, in order to differentiate such methods from top-level or local functions.

I'm going to talk about why we need self.

When we define a class, like:

class MyClass {
    func myMethod()
}

We are creating a Class Object. Yes, Class is an object too.

Then no matter how many instances are created using the class, all instances will have a reference points to its Class Object.

You can image that all instance methods defined by the Class are in the Class Object, and there will be only one copy of them.

That means all instances created using the Class are sharing the same method.

Now imaging that you are the myMethod in the Class Object, and because you are shared for all instances, you must have a way to tell which instance you are working on.

When someone says instance1.myMethod(), it means "Hi! myMethod, please do your work and instance1 is the object you are working on".

How do you reference the object that the caller sent to you, use self.

Correct me if I'm wrong, thank you.

“In practice, you don’t need to write self in your code very often. If you don’t explicitly write self, Swift assumes that you are referring to a property or method of the current instance whenever you use a known property or method name within a method.”

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/tw/jEUH0.l

Nikita Kurtin

First of all: Good answers, examples and explanations already posted here, although I must to point something out:

Reserved word: self in swift is similar to this but it's not the same as in Java or Javascript.

As @Dave Gomez correctly quoted:

Every instance of a type has an implicit property called self, which is exactly equivalent to the instance itself.

And here starts one of the main differences, because:

  1. "Every instance" in swift (at least for now) is almost Every-thing
  2. When in Java (for example) you can only use word this inside an instance scope, in swift you can use it almost Every-where

Here a few examples:

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

If you want to read more, please see : Why 'self.self' compiles and run in swift

The OP question is about what it is in swift, so I won't bore readers with explanations what it is in Java or Javascript (But if some readers need it just write a comment).

The following article explains self in details:

How to use correctly 'self' keyword in Swift


self is a property on the instance that refers to itself. It's used to access class, structure and enumeration instance within methods.

When self is accessed in a type method (static func or class func), it refers to the actual type (rather than an instance).

Swift allows to omit self when you want to access instances properties.

When a method parameter have the same name as instance property, you have to explicitly use self.myVariable = myVariable to make a distinction. Notice that method parameters have a priority over instance properties.

self is a property on the instance that refers to itself. It's used to access class, structure and enumeration instance within methods. When a method parameter have the same name as instance property, you have to explicitly use self.myVariable = myVariable to make a distinction. Notice that method parameters have a priority over instance properties.

    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

I arrived at this question (& answers) while searching for self as a class function, which looks like this: Int.self, String.self, or YourClass.self

Previously, as near as I can tell, only Dmitri Pavlutin's answer touches on this, when he said:

When self is accessed in a type method (static func or class func), it refers to the actual type (rather than an instance).

When self is used this way, it actually returns what in Swift is called a Metatype. You can read the documentation about this here: https://docs.swift.org/swift-book/ReferenceManual/Types.html#//apple_ref/swift/grammar/metatype-type

There is also a very nice article with examples on using metatypes on swiftrocks.com.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!