我对Swift还不熟悉,想知道self
是用来做什么的。
我在类和结构体中看到了它,但我觉得它们并不重要,甚至没有必要在我的代码中提及。它们是用来干什么的?在什么情况下需要使用它?
我已经阅读了很多关于这个问题的问答,但没有一个完全回答了我的问题,它们总是倾向于将其与Java中的this
进行比较,而我对Java一无所知。
是的,它与Java中的this
和Objective-C中的self
相同,但在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 theself
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 += 1 }
In practice, you don’t need to write
self
in your code very often. If you don’t explicitly writeself
, 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 ofcount
(rather thanself.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 calledx
and an instance property that is also calledx
:”
摘自:苹果公司《Swift编程语言(Swift 2预发布版)》
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)
}
}
}
self
的建议:
当访问只有在必要时才明确引用
self
self
的属性或方法时,默认情况下将对self
的引用留作隐式。private class History {
var events: [Event]
func rewrite() {
events = []
}
}
只有在语言需要的情况下才包含显式关键字,例如在闭包中或者参数名称发生冲突时:
extension History {
init(events: [Event]) {
self.events = events
}
var whenVictorious: () -> () {
return {
self.rewrite()
}
}
}
原因:这使得在闭包中更加突出了self的捕获语义,并避免了其他地方的冗长。
this
也可以出于同样的原因以同样的方式使用。 - Dmitry Gryazin在创建扩展时,你也会经常使用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
现在假设您想要更改变量result本身,则必须使用mutating 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"
这就是为什么我们需要self
。
当我们定义一个类时,例如:
class MyClass {
func myMethod()
}
我们正在创建一个“类对象”。是的,Class也是一个对象。
然后,无论使用类创建了多少个实例,所有实例都将具有指向其Class对象的引用指针。
你可以想象由Class定义的所有实例方法都在Class对象中,而且只会有一个副本。
这意味着使用Class创建的所有实例共享同一方法。
现在想象一下,你是Class对象中的myMethod
,因为你被所有实例共享,所以你必须有一种方法来告诉自己正在处理哪个实例。
当有人说instance1.myMethod()
时,它的意思是“嗨!myMethod
,请完成你的工作,instance1
是你正在处理的对象”。
要引用调用者发送给你的对象,请使用self
。
“实际上,在你的代码中你不需要经常写self。如果你没有显式地写self,Swift假设每当你在方法中使用已知的属性或方法名称时,你都在引用当前实例的一个属性或方法。”
摘自:Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/tw/jEUH0.l
self
类似于Java或JavaScript中的this
,但并不完全相同。这里有一个主要的区别,因为:每个类型的实例都有一个隐式属性称为 self,它与实例本身完全等效。
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)
我在搜索类函数self
时遇到了这个问题,它看起来像这样:Int.self
、String.self
或YourClass.self
。
据我所知,之前仅有 Dmitri Pavlutin 的回答触及了这个问题,他说:
当在类型方法(static func 或 class func)中访问
self
时,它指的是实际的类型(而不是实例)。
当以这种方式使用self
时,它实际上返回 Swift 中称为 Metatype 的东西。您可以阅读Swift 类型文档页面获取更多信息。
还有一篇关于使用和理解元类型的更详细文章,名为“.self、.Type 和 .Protocol 是什么?理解 Swift 元类型”,可以在 swiftrocks.com 上找到。
self
。
self
是指向其自身的实例上的属性。它用于在方法内部访问类、结构体和枚举实例。self
,例如static func
或class func
时,它引用的是实际类型而不是实例。self
。self.myVariable = myVariable
来区分它们。注意,方法参数优先于实例属性。我对编程完全不了解,虽然这些答案很好,但对于像我这样只想尽可能简单地回答问题而不涉及难词和概念的编程新手来说,这是我精简版的超级新手版本:
使用'self'是因为编码应用程序不知道如果您在函数范围内键入变量,则要使用哪个变量。这都与作用域有关,需要明确使用哪个变量,如果其他变量具有相同的名称,则需要进行区分。作用域是花括号{}内的区域。例如:
{ scope1 {scope2} }
在此示例中,您无需使用self:
class example {
private var exampleVar = “this is the class scope variable”
func x() {
//You don't have to use self here
print(exampleVar)
}
}
这里需要使用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)
}
}
还有这种情况:
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)
}
}
}
self
是实例上的一个属性,指向自身。它用于在方法内部访问类、结构体和枚举实例。
当方法参数与实例属性同名时,必须显式使用self.myVariable = myVariable
来区分。
请注意,方法参数优先于实例属性。
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
我有一个在Swift中使用self
的优雅案例。我在像这样的块中使用它:
class MyBase {
private var baseValue: Int = 100
var block: ((Int)->())? = nil
func baseMethod(anotherValue: Int) {
guard let b = block else { return }
b(baseValue + anotherValue)
}
...
}
class MyClass {
init()
{
// Define base class block.
// This may hold self in block causing memory leaks
// if self is a strong reference
block = {
// indicate self is a weak reference
[weak self] (para) in
// guaranty self existence
guard let this = self else {return}
let value = this.value1 + para
// this call passes value to other obj's method
this.obj.method(value)
return
}
}
func callBaseBlock(otherValue: Int) {
baseMethod(otherValue)
}
private var value1: Int = 1 // ini value
private var obj: OtherClass // another class with method defined
...
...
}
这样,我保证在块中不会有对self
的强引用。语法非常清晰。我使用这种方式来防止内存泄漏。
self
是什么意思,还是为什么有时候(经常)可以省略它(因为它已经被暗示了)? - Thilo