ios Swift 中的“self”是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26835013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:33:48  来源:igfitidea点击:

What is "self" used for in Swift?

iosswiftself

提问by Lucas Martin Calderon

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

我是 Swift 的新手,我想知道self用于什么以及为什么。

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 thisas in Java, with which I'm not familiar whatsoever.

我一直在阅读有关这个​​问题的很多问题和答案,但没有一个完全回答我的问题,而且他们总是倾向于将其与thisJava 中的进行比较,而我对此并不熟悉。

采纳答案by Leo Dabus

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 结果本身,你必须使用变异函数来改变自己

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"

回答by David Gomez

Yes it is the same as thisin Java and selfin Objective-C, but with Swift, selfis only required when you call a property or method from a closure or to differentiate property names inside your code, such as initializers. So you can use almost all of your class components safely without using selfunless you are making the call from a closure.

是的,它与thisJava 和selfObjective-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 selfproperty 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 += 1
}

In practice, you don't need to write selfin 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 selfproperty to distinguish between the parameter name and the property name.

Here, selfdisambiguates between a method parameter called xand an instance property that is also called x:”

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

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

func increment() {
    self.count += 1
}

实际上,您不需要self经常编写代码。如果你没有明确写出self,Swift 会假设你在一个方法中使用一个已知的属性或方法名称时,你指的是当前实例的一个属性或方法。这个假设通过在Counter 的三个实例方法中使用count(而不是self.count)来证明。

当实例方法的参数名称与该实例的属性名称相同时,会发生此规则的主要例外。在这种情况下,参数名称优先,因此有必要以更限定的方式引用属性。您使用self属性来区分参数名称和属性名称。

在这里,self消除了称为方法参数x和也称为 的实例属性之间的歧义x:”

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

摘自:Apple Inc. “The Swift Programming Language (Swift 2 Prerelease)”。



This is how Ray Wenderlichrecommends the use of selfin Swift for their tutorials:

这就是Ray Wenderlichself在他们的教程中推荐在 Swift 中使用的方式:

Use of Self

自我的使用

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

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

Use selfwhen 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 is GitHub's recommendations on selffor their applications:

这是GitHubself对其应用程序的建议:

Only explicitly refer to selfwhen required

self在需要时明确引用

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

在访问 上的属性或方法时selfself默认情况下将引用保留为隐式:

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 的捕获语义在闭包中更加突出,并避免了其他地方的冗长。

回答by matt

In what situations it's necessary to use it

什么情况下需要使用

It is necessaryto 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.

  • 我将它与属性名称一起使用,否则我会想知道这个变量是什么(因为它既不是本地声明的也不是传入参数)。

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

回答by ylin0x81

This is why we need self.

这就是为什么我们需要self.

When we define a class, like:

当我们定义一个类时,例如:

class MyClass {
    func myMethod()
}

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

我们正在创建一个“类对象”。是的,Class 也是一个对象。

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

那么无论使用该类创建了多少个实例,所有实例都会有一个指向其类对象的引用指针。

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

可以想象,Class 定义的所有实例方法都在 Class Object 中,并且只会有一个副本。

enter image description here

在此处输入图片说明

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

这意味着使用 Class 创建的所有实例都共享相同的方法。

Now imagine you are the myMethodin 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 instance1is the object you are working on".

当有人说时instance1.myMethod(),它的意思是“嗨!myMethod,请做你的工作,instance1是你正在工作的对象”。

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

要引用调用者发送给您的对象,请使用self.

“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

“实际上,您不需要经常在代码中编写 self。如果你没有明确地写出 self ,当你在一个方法中使用一个已知的属性或方法名称时,Swift 会假设你指的是当前实例的一个属性或方法。”

摘自:Apple Inc. “The Swift Programming Language”。电子书。 https://itun.es/tw/jEUH0.l

回答by Nikita Kurtin

The reserved word selfin Swift is similar to thisbut it's not the same as in Java or JavaScript.

selfSwift 中的保留字与thisJava 或 JavaScript 中的保留字类似但又不同。

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 的隐式属性,它完全等同于实例本身。

Here lies one of the main differences, because:

这是主要区别之一,因为:

  1. "Every instance"in Swift (at least for now) is almost every-thing.
  2. In Java, for example, you can only use the word thisinside an instance scope, in Swift you can use it almost every-where.
  1. Swift 中的“每个实例”(至少现在)几乎是所有东西
  2. 例如,在 Java 中,您只能this在实例范围内使用该词,而在 Swift 中,您几乎可以在任何地方使用它。

Here are 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)

See : Why 'self.self' compiles and run in swiftfor more information.

有关更多信息,请参阅:Why 'self.self' compiles and run in swift了解更多信息。

回答by Dmitri Pavlutin

"How to use correctly 'self' keyword in Swift" explains selfin detail.

如何在 Swift 中正确使用 'self' 关键字self详细解释了。

selfis 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 like static funcor class func, it refers to the actual type rather than an instance.

当 self 在像static funcor 之类的类型方法中访问时class func,它指的是实际类型而不是实例。

Swift allows omitting selfwhen you want to access instances properties.

Swift 允许self在您想要访问实例属性时省略。

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

当方法参数与实例属性同名时,必须显式使用self.myVariable = myVariable来区分。请注意,方法参数优先于实例属性。

回答by livingtech

I arrived at this question while searching for selfas a class function, which looks like this: Int.self, String.self, or YourClass.self

我在搜索self类函数时遇到了这个问题,它看起来像这样:Int.self, String.self, 或YourClass.self

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

以前,据我所知,只有德米特里·帕夫卢廷 (Dmitri Pavlutin) 的回答触及了这一点,他说:

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 时,它指的是实际类型(而不是实例)。

When selfis used this way, it actually returns what in Swift is called a Metatype. You can read the Swift documentation page on Typesfor more information.

self以这种方式使用时,它实际上返回 Swift 中称为元类型的内容。您可以阅读关于类型Swift 文档页面以获取更多信息。

There is also an article with more details about using and understanding metatypes called "What's .self, .Type and .Protocol? Understanding Swift Metatypes"on swiftrocks.com.

swiftrocks.com 上还有一篇文章,其中包含有关使用和理解元类型的更多详细信息,称为“什么是 .self、.Type 和 .Protocol?Understanding Swift Metatypes”

回答by Super Noob

I'm a total noob at coding in general - and whilst these answers are great, from the perspective of a total noob who just wants it answered as practically as possible without all these difficult words and concepts, here's my Super Noob dumbed down version:

总的来说,我在编码方面是个菜鸟——虽然这些答案很好,但从一个只想尽可能实际地回答它而没有所有这些困难的词和概念的菜鸟的角度来看,这是我的超级菜鸟简化版:

'self' is used because the coding application doesn't know which variable to use if you type the variable in the scope of your functions. It's all about the scope and making it clear which variable you're using if some other variable has the same name. Scope is the area inside the curly {} brackets. so for example:

使用“self”是因为如果您在函数范围内键入变量,编码应用程序不知道要使用哪个变量。如果其他变量具有相同的名称,这一切都与作用域有关,并明确说明您正在使用哪个变量。范围是大括号 {} 内的区域。所以例如:

{ scope1 {scope2} }

{ scope1 {scope2} }

Here you don't need to use self:

在这里你不需要使用 self:

class example {
    private var exampleVar = “this is the class scope variable”

    func x() {
        //You don't have to use self here
        print(exampleVar)
    }
}

Here you do need to use self:

在这里,您确实需要使用 self:

class example {
        private var exampleVar = “this is the class scope variable”

        func x(_ exampleVar: String) {
            //It would be confusing which exampleVar is used here so you should use self
            print(exampleVar)
            print(self.exampleVar)
        }
}

There's also this situation:

还有这种情况:

class example {
    private var exampleVar = “this is the class scope variable”

    func x() {
        randomMethod { _ in
            //This is not the class scope here, so we need to use self here.
            //You will be flagged during build time of this if you don't use self.
            print(self.exampleValue)                     
        }
    }
}

回答by Akbar Khan

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

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

When a method parameter has the same name as an instance property, you have to explicitly use self.myVariable = myVariableto make a distinction.

当方法参数与实例属性同名时,必须显式使用self.myVariable = myVariable来区分。

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