Unterscheidung in Swift zwischen Großbuchstaben „Selbst“ und Kleinbuchstaben „Selbst“


74

Während ich auf einem Swift-Spielplatz spielte, bemerkte ich, dass Selfmit Großbuchstaben "S" neben Kleinbuchstaben auch verfügbar ist self. Gibt es einen Unterschied zwischen ihnen? Wenn ja, wofür werden diese beiden verwendet, insbesondere für Self?


1
Es gibt einige Nuancen in Bezug auf die Werte von selfund Selfin Protokollerweiterungen - darauf gehe ich in diesen Fragen und Antworten ausführlich ein .
Hamish

Antworten:


82

Selfbezieht sich auf den Typ des aktuellen "Dings" innerhalb eines Protokolls (was auch immer dem Protokoll entspricht). Ein Beispiel für seine Verwendung finden Sie unter Protokollfunktion, die Self zurückgibt .

Die offiziellen Dokumente, für die ich gefunden habe, befinden sich Selfin der protokollassoziierten Typdeklaration in der Programmiersprache Swift. Es ist überraschenderweise nicht in den Abschnitten über Protokolle oder verschachtelte Typen dokumentiert:

Jetzt gibt es jedoch einen Absatz über die AufnahmeSelf Type eines Codebeispiels in das offizielle Kapitel der Swift Programming Language über Typen


3
Ich habe einen wählerischen, pedantischen Tag. Aber mach dir keine Sorgen! Ich habe mir die Zeit genommen, meine Freunde zu entfremden, um zu sagen: Um die Frage technisch vollständig zu beantworten, sollte diese Antwort ausdrücklich sagen, dass dies selfweitgehend das ist, was Objective-C-Leute denken. Die Diskussion über Strukturen, Aufzählungen usw. ist wahrscheinlich ein unnötiger Umweg.
Tommy

Siehe "Protocol Associated Type Declaration" in der Sprachreferenz: developer.apple.com/library/prerelease/ios/documentation/Swift/…
Rob Napier

12
Es wird im WWDC 2015-Video zur protokollorientierten Programmierung sehr gut behandelt: developer.apple.com/videos/wwdc/2015/?id=408 - das genaue Stück zum Selbsttyp finden Sie im Video unter 16:05.
Sez

10

Selfkann auch in Klassen verwendet werden und ist nützlich. Hier ist ein Artikel darüber.

Hier ist ein Beispiel. Sie haben eine Klasse namens MyClass. MyClassMethoden haben, die Instanzen davon zurückgeben. Jetzt fügen Sie eine Unterklasse von MyClassaufgerufen hinzu MySubclass. Sie möchten, dass diese Methoden Instanzen von MySubclassstatt zurückgeben MyClass. Der folgende Code zeigt, wie es geht. Beachten Sie, dass die Methoden entweder Instanzmethoden oder Klassenmethoden sein können.

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)

Die folgende Zeile wurde ausgedruckt:

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

8

Verwenden Sie in der Protokoll- und Erweiterungsdeklaration Self else self

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

IMO, das wherehier ist ein hervorragendes Beispiel dafür, was Selfist.
24.

4

Ich denke, diese Frage könnte eine einfachere Antwort gebrauchen, die sich mehr auf den Unterschied zwischen Selfund konzentriert selfund sich möglicherweise an Personen richtet, die Swift noch nicht kennen.

self - expliziter Verweis auf den aktuellen Typ oder die Instanz des Typs, in dem er vorkommt.

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

Self- Wird speziell in protocolund extensionDeklarationen verwendet , um auf den möglichen Typ zu verweisen, der dem Protokoll entspricht.

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

class MyClass: MyProtocol {
   // define class
}

MyClass.returnSelf() 
// returns MyClass

Der Unterschied besteht darin, dass selfin Typen und Instanzen von Typen verwendet wird, um auf den Typ zu verweisen, in dem er sich befindet. und Selfwird in Protokollen und Erweiterungen verwendet, bei denen das tatsächliche typenoch nicht bekannt ist.

In noch einfacheren Worten, selfwird innerhalb eines vorhandenen Typs verwendet; Selfwird verwendet, um auf einen Typ zu verweisen, der Selfnoch nicht vorhanden ist.

Lesen Sie hier mehr:


1

Self kann auch als Rückgabetyp im Protokollerweiterungsmethoden-Body verwendet werden, der eine bestätigende Typinstanz zurückgibt, und für das Typ-Casting mit "as". Siehe Beispiel unten:

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

Kurz gesagt, Self kann verwendet werden, um den Typ zu referenzieren, der das Protokoll bestätigt.


1

Ich verstehe Self als Typnamen (z. B. Klassenname) und self als Instanz einer Klasse / Struktur, zum Beispiel:

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

    }
}

Sie können self nicht mit einer statischen Eigenschaft verwenden, aber Sie können Self verwenden

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.