什么是Swift中使用的“自我”?

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

我已经在类和结构中看到了它,但是我实际上并没有发现它们在我的代码中甚至提及它们是必要的也是不必要的。 他们用了什么,为什么? 在什么情况下有必要使用它?

我一直在阅读很多关于这个问题的问题和答案,但是他们没有一个完全回答我的问题,他们总是倾向于把它与Java中的相比,我对此并不熟悉。

创build扩展程序时,您也会使用很多自己的function,例如:

 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结果本身,你必须使用mutating func来改变它本身

 var z = 3 println(z) // 3 

现在让我们改变它

 z.squareMe() println(z) // 9 

//现在让我们看看另一个使用string

 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" 

更新:2015年11月24日

是的, thisObjective-C中的Javaself是一样的,但是对于Swift来说 ,当你从一个闭包中调用一个属性或方法或区分代码中的属性名称( 例如初始值设定项)时,self就是必需的。 所以你可以安全地使用几乎所有的类组件,而不需要使用self,除非你从闭包中调用。

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

上例中的increment()方法可能是这样写的:

 func increment() { self.count++ } 

在实践中,你不需要经常写self的代码。 如果你没有明确地写self ,Swift假设你在方法中使用一个已知的属性或方法名称时,指的是当前实例的一个属性或方法。 Counter的三个实例方法中使用了count (而不是self.count )就可以certificate这个假设。

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

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

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


这就是Ray Wenderlichbuild议在Swift中使用self的教程:

使用自我

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

在需要时使用self来区分初始化程序中的属性名称和参数,以及引用闭包expression式中的属性时(如编译器所要求的那样):

 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

当访问自己的属性或方法时,默认情况下将引用保留为隐式:

 private class History { var events: [Event] func rewrite() { events = [] } } 

只有在语言要求时才包含显式关键字 – 例如,在闭包中,或参数名称冲突时:

 extension History { init(events: [Event]) { self.events = events } var whenVictorious: () -> () { return { self.rewrite() } } } 

理由:这使得自我的捕捉语义在更多的closures中脱颖而出,避免了其他地方的冗长。

在什么情况下有必要使用它

仅当局部variables的名称遮盖了属性的名称时,才有必要使用它。

然而,作为风格 (和可读性)的问题,我总是使用它:

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

  • 我使用它作为函数(方法)调用的接收器,以区分这些方法与顶级或本地函数。

我要谈谈为什么我们需要self

当我们定义一个类,如:

 class MyClass { func myMethod() } 

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

然后,无论使用该类创build了多less个实例,所有实例都将有一个对其类对象的引用。

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

在这里输入图像说明

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

现在想象一下,您是类对象中的myMethod ,并且由于您为所有实例共享,所以您必须有办法告诉您正在处理哪个实例。

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

你如何引用调用者发送给你的对象,使用self

纠正我,如果我错了,谢谢。

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

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

首先:在这里已经发布了很好的答案,例子和解释,但我必须指出:

保留字:swift中的selfthis类似, 但与Java或Javascript中的不同

正如@Dave Gomez正确地引用了:

每个types的实例都有一个名为self的隐式属性,它与实例本身是完全等价的。

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

  1. 迅速(至less现在)的“每个实例”几乎是一切
  2. 当在Java中(例如)你只能在一个实例范围内使用这个词,在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) 

如果你想阅读更多的内容,请看: 为什么“self.self”编译和运行迅速

OP的问题是关于什么是快速的,所以我不会让读者解释它是什么在Java或Javascript(但如果有些读者需要它只是写评论)。

以下文章详细解释了self

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


self是指自己的实例的属性。 它用于访问方法内的类,结构和枚举实例。

当在types方法( static funcclass func )中访问self时,它指的是实际的types(而不是实例)。

当你想访问实例属性时,Swift允许省略self

当一个方法参数与实例属性名称相同时,您必须明确使用self.myVariable = myVariable来区分。 请注意,方法参数优先于实例属性。