Swift在大写字母“ Self”和小写字母“ self”之间的区别


75

在Swift操场上玩耍时,我注意到Self大写字母“ S”与小写字母一起可用self。它们之间有什么区别吗?如果是这样,那么这两个的用法是什么,尤其是对于Self


1
关于selfSelf协议扩展的值有很多细微差别–在本问答中,我将对此进行详细介绍。
Hamish

Answers:


82

Self指协议内部当前“事物”的类型(无论符合什么协议)。有关其用法的示例,请参见协议函数返回Self

我已经找到了官方的文档Self协议相关联的类型声明中的斯威夫特编程语言。令人惊讶的是,在有关协议或嵌套类型的部分中没有进行记录:

但是,现在在官方的Swift编程语言关于类型章节中一段关于Self Type包含代码示例的段落。


3
我今天很挑剔,很书呆子。但是不用担心!我已经抽出时间让我的朋友疏远了:要从技术上完全回答这个问题,这个答案应该明确地说这self就是Objective-C人们的想法。通过讨论结构,枚举等,可能是不必要的绕道。
汤米

请参阅“协议相关联的类型声明”中的语言参考:developer.apple.com/library/prerelease/ios/documentation/Swift/...
罗布内皮尔

12
在WWDC 2015面向协议编程的视频中,它的内容非常好:developer.apple.com/videos/wwdc/2015/? id = 408-有关视频中关于“自我”类型的确切内容,请转到视频16 :5 。
Sez

10

Self也可以在类中使用,并且很有用。是一篇关于它的文章。

这是一个例子。您有一个名为的课程MyClassMyClass有方法返回它的实例。现在,您添加了一个MyClass名为的子类MySubclass。您希望这些方法返回的实例,MySubclass而不是MyClass。以下代码显示了如何执行此操作。请注意,这些方法可以是实例方法或类方法。

class MyClass: CustomStringConvertible {

    let text: String

    // Use required to ensure subclasses also have this init method
    required init(text: String) {
        self.text = text
    }

    class func create() -> Self {
        return self.init(text: "Created")
    }

    func modify() -> Self {
        return type(of: self).init(text: "modifid: " + text)
    }

    var description: String {
        return text
    }

}

class MySubclass: MyClass {
    required init(text: String) {
        super.init(text: "MySubclass " + text)
    }
}

let myClass = MyClass.create()
let myClassModified = myClass.modify()

let mySubclass = MySubclass.create()
let mySubclassModified = mySubclass.modify()

print(myClass)
print(myClassModified)
print(mySubclass)
print(mySubclassModified)

打印以下行:

// Created
// modifid: Created
// MySubclass Created
// MySubclass modifid: MySubclass Created

8

在协议和扩展声明中使用Self else self

extension protocolName where Self: UIView 
{
  func someFunction()
  {
    self.layer.shadowColor = UIColor.red.cgColor
  }
}

海事组织,where这是一个很好的例子Self
thedp

4

我认为这个问题可以用一个简单的答案,更多的集中于差异之间Selfself,也许是针对那些较新的斯威夫特。

self -显式引用当前类型或类型的实例。

class MyClass {
  func showClass() {
       print("\(self)")
    }
  }
let someClass = MyClass()
someClass.showClass()
// prints "MyClass"

Self-protocolextension声明中专门使用,指代符合协议的最终类型。

protocol MyProtocol {
   static func returnSelf() -> Self
}

class MyClass: MyProtocol {
   // define class
}

MyClass.returnSelf() 
// returns MyClass

区别在于,self在类型和类型的实例中使用它来引用它所在的类型;并且Self用于实际type未知的协议和扩展中。

更简单地说,self是在现有类型中使用;Self用于指代Self尚未使用的类型。

在这里阅读更多:


1

在协议扩展方法主体中,Self也可以用作返回类型,该类型将返回确认类型实例,并使用“ as”进行类型转换。请参见下面的示例:

extension <Protocol-Name> where Self:<Class-Name> {
static func foo(_ param:Type)-> Self{
    guard let abc = method() as? Self else{
        return xyz
    }
}}

简而言之,Self可以用来引用确认协议的Type。


1

我将Self理解为类型名(例如,类名),将self理解为类/ struct的实例,例如:

struct Person {
     static var documentNumner = "9484930"
     var name: String
     var computedFullName: String {
        return ("\(self.name) with document number: \(Self.documentNumner)")

    }
}

您不能将self与静态属性一起使用,但是可以使用Self

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.