Swift中“self”的含义是什么?

时间:2022-07-21 16:02:10

I am new to Swift and I'm wondering what self is used for and why.

我是斯威夫特的新手,我想知道自我是用来做什么的,为什么。

I have seen it in classes and structures but I really don't find them essential nor necessary to even mention them in my code. What are they used for and why? In what situations it's necessary to use it?

我在类和结构中见过它,但我真的觉得它们没有必要,甚至在代码中也没有必要提到它们。它们的用途是什么?为什么?在什么情况下需要使用它?

I have been reading lots of questions and answers for this question but none of them fully answers my questions and they always tend to compare it with this as in Java, with which I'm not familiar whatsoever.

我已经读了很多关于这个问题的问题和答案,但是没有一个能完全回答我的问题,他们总是倾向于将它与Java进行比较,我对Java并不熟悉。

6 个解决方案

#1


22  

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

在创建扩展时,您也会经常使用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

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

现在假设您想要更改var结果本身,您必须使用突变func来进行更改

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

myString1.replicateMe(3)

println(myString1)         // "AbcAbcAbc"

#2


54  

Update: November 24, 2015

更新:2015年11月24日

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.

是的,它与Java和self在Objective-C中是一样的,但是在Swift中,只有当您从闭包中调用属性或方法或在代码中区分属性名(例如初始化器)时,才需要self。所以您可以安全地使用所有的类组件,而不使用self,除非您从闭包中发出调用。

“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.

“self属性类型的每个实例都有一个隐式属性self,它与实例本身完全等价。您可以使用self属性在自己的实例方法中引用当前实例。

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

上面示例中的increment()方法可以这样写:

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.

实际上,您不需要经常在代码中编写self。如果您没有显式地编写self, Swift假设您在使用方法中已知的属性或方法名称时引用当前实例的属性或方法。通过在计数器的三个实例方法中使用count(而不是self.count)来演示这个假设。

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.

当实例方法的参数名称与实例的属性具有相同的名称时,就会出现此规则的主要异常。在这种情况下,参数名称优先,有必要以更合格的方式引用属性。您可以使用self属性来区分参数名和属性名。

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

在这里,self消除了方法参数x和实例属性x之间的歧义。

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

摘自:苹果公司“Swift编程语言(Swift 2预发行)”。


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

这就是Ray Wenderlich建议在Swift中使用self的方法:

Use of Self

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

为了简洁,避免使用self,因为Swift不要求它访问对象的属性或调用它的方法。

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

当需要区分初始化器中的属性名和参数时,以及引用闭包表达式中的属性时(按照编译器的要求),请使用self:

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:

以下是GitHub对self的推荐:

Only explicitly refer to self when required

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

在访问属性或方法时,默认将引用保留为self隐式:

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.

基本原理:这使得self的捕获语义在闭包中更加突出,并且避免了其他地方的冗长。

#3


13  

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.

    我将它用作函数(方法)调用的接收者,以便将这些方法与*函数或本地函数区分开来。

#4


9  

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.

您可以想象类定义的所有实例方法都在类对象中,并且它们只有一个副本。

Swift中“self”的含义是什么?

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.

现在假设您是类对象中的myMethod,并且由于您对所有实例都是共享的,所以您必须有一种方法来判断您正在处理哪个实例。

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

当有人说instance1.myMethod()时,它的意思是“Hi!”myMethod,请执行您的工作,instance1是您正在处理的对象。

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

如何引用调用者发送给您的对象,使用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.”

在实践中,您不需要经常在代码中编写self。如果不显式地编写self, Swift假设您在使用方法中已知的属性或方法名称时引用当前实例的属性或方法。

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

摘自:苹果公司“Swift编程语言”。“iBooks。https://itun.es/tw/jEUH0.l

#5


5  

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.

保留字:在swift中的self与此类似,但与Java或Javascript中的self不同。

As @Dave Gomez correctly quoted:

正如@Dave Gomez所言:

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

类型的每个实例都有一个隐式属性self,它与实例本身完全等价。

And here starts one of the main differences, because:

这里开始了一个主要的区别,因为:

  1. "Every instance" in swift (at least for now) is almost Every-thing
  2. swift中的“每一个实例”(至少现在是这样)几乎就是一切
  3. When in Java (for example) you can only use word this inside an instance scope, in swift you can use it almost Every-where
  4. 在Java中(例如),您只能在实例范围内使用这个词,在swift中,您几乎可以在任何地方使用它

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

如果你想读得更多,请看:为什么是“自我”。self快速编译并运行

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

OP的问题是关于它在swift中是什么,所以我不会用Java或Javascript的解释让读者感到厌烦(但如果有些读者需要的话,只需写一条注释)。

#6


3  

The following article explains self in details:

下面的文章详细解释了self:

How to use correctly 'self' keyword in Swift

如何在Swift中正确使用“self”关键字


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

self是实例上引用自身的属性。它用于访问方法中的类、结构和枚举实例。

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

当在类型方法(静态func或类func)中访问self时,它引用的是实际类型(而不是实例)。

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

当您想要访问实例属性时,Swift允许省略自己。

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。myVariable = myVariable进行区分。注意,方法参数比实例属性具有优先级。

#1


22  

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

在创建扩展时,您也会经常使用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

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

现在假设您想要更改var结果本身,您必须使用突变func来进行更改

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

myString1.replicateMe(3)

println(myString1)         // "AbcAbcAbc"

#2


54  

Update: November 24, 2015

更新:2015年11月24日

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.

是的,它与Java和self在Objective-C中是一样的,但是在Swift中,只有当您从闭包中调用属性或方法或在代码中区分属性名(例如初始化器)时,才需要self。所以您可以安全地使用所有的类组件,而不使用self,除非您从闭包中发出调用。

“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.

“self属性类型的每个实例都有一个隐式属性self,它与实例本身完全等价。您可以使用self属性在自己的实例方法中引用当前实例。

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

上面示例中的increment()方法可以这样写:

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.

实际上,您不需要经常在代码中编写self。如果您没有显式地编写self, Swift假设您在使用方法中已知的属性或方法名称时引用当前实例的属性或方法。通过在计数器的三个实例方法中使用count(而不是self.count)来演示这个假设。

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.

当实例方法的参数名称与实例的属性具有相同的名称时,就会出现此规则的主要异常。在这种情况下,参数名称优先,有必要以更合格的方式引用属性。您可以使用self属性来区分参数名和属性名。

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

在这里,self消除了方法参数x和实例属性x之间的歧义。

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

摘自:苹果公司“Swift编程语言(Swift 2预发行)”。


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

这就是Ray Wenderlich建议在Swift中使用self的方法:

Use of Self

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

为了简洁,避免使用self,因为Swift不要求它访问对象的属性或调用它的方法。

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

当需要区分初始化器中的属性名和参数时,以及引用闭包表达式中的属性时(按照编译器的要求),请使用self:

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:

以下是GitHub对self的推荐:

Only explicitly refer to self when required

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

在访问属性或方法时,默认将引用保留为self隐式:

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.

基本原理:这使得self的捕获语义在闭包中更加突出,并且避免了其他地方的冗长。

#3


13  

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.

    我将它用作函数(方法)调用的接收者,以便将这些方法与*函数或本地函数区分开来。

#4


9  

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.

您可以想象类定义的所有实例方法都在类对象中,并且它们只有一个副本。

Swift中“self”的含义是什么?

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.

现在假设您是类对象中的myMethod,并且由于您对所有实例都是共享的,所以您必须有一种方法来判断您正在处理哪个实例。

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

当有人说instance1.myMethod()时,它的意思是“Hi!”myMethod,请执行您的工作,instance1是您正在处理的对象。

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

如何引用调用者发送给您的对象,使用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.”

在实践中,您不需要经常在代码中编写self。如果不显式地编写self, Swift假设您在使用方法中已知的属性或方法名称时引用当前实例的属性或方法。

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

摘自:苹果公司“Swift编程语言”。“iBooks。https://itun.es/tw/jEUH0.l

#5


5  

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.

保留字:在swift中的self与此类似,但与Java或Javascript中的self不同。

As @Dave Gomez correctly quoted:

正如@Dave Gomez所言:

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

类型的每个实例都有一个隐式属性self,它与实例本身完全等价。

And here starts one of the main differences, because:

这里开始了一个主要的区别,因为:

  1. "Every instance" in swift (at least for now) is almost Every-thing
  2. swift中的“每一个实例”(至少现在是这样)几乎就是一切
  3. When in Java (for example) you can only use word this inside an instance scope, in swift you can use it almost Every-where
  4. 在Java中(例如),您只能在实例范围内使用这个词,在swift中,您几乎可以在任何地方使用它

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

如果你想读得更多,请看:为什么是“自我”。self快速编译并运行

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

OP的问题是关于它在swift中是什么,所以我不会用Java或Javascript的解释让读者感到厌烦(但如果有些读者需要的话,只需写一条注释)。

#6


3  

The following article explains self in details:

下面的文章详细解释了self:

How to use correctly 'self' keyword in Swift

如何在Swift中正确使用“self”关键字


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

self是实例上引用自身的属性。它用于访问方法中的类、结构和枚举实例。

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

当在类型方法(静态func或类func)中访问self时,它引用的是实际类型(而不是实例)。

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

当您想要访问实例属性时,Swift允许省略自己。

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。myVariable = myVariable进行区分。注意,方法参数比实例属性具有优先级。