webentwicklung-frage-antwort-db.com.de

Was ist ein gutes Beispiel, um in Swift3 zwischen fileprivate und private zu unterscheiden

Dieser Artikel hat zum Verständnis der neuen Zugriffsspezifizierer in Swift 3 Beigetragen. Es werden auch einige Beispiele für unterschiedliche Verwendungen von fileprivate und private aufgeführt.

Meine Frage lautet: Wird fileprivate nicht für eine Funktion verwendet, die nur in dieser Datei verwendet wird, genauso wie private?

133
Nikita P

fileprivate ist jetzt das, was private in früheren Swift Releases: Zugriff aus derselben Quelldatei. Eine als private markierte Deklaration kann Jetzt kann nur innerhalb des lexikalischen Bereichs zugegriffen werden, in dem es deklariert ist. Daher ist private restriktiver als fileprivate.

Ab Swift 4 können Erweiterungen desselben Typs auf private Deklarationen innerhalb eines Typs zugreifen, wenn die Erweiterung in derselben Quelldatei definiert ist.

Beispiel (alles in einer Quelldatei):

class A {
    private func foo() {}
    fileprivate func bar() {}

    func baz() {
        foo()
        bar()
    }
}

extension A {
    func test() {
        foo() // Swift 3: error: use of unresolved identifier 'foo'
              // Swift 4: no error because extension is in same source file
        bar()
    }
}

let a = A()
a.foo() // error: 'foo' is inaccessible due to 'private' protection level
a.bar()
  • Auf die private foo -Methode kann nur im Rahmen der class A { ... } Definition. Es ist nicht einmal von einer Erweiterung für den Typ zugänglich (in Swift 3, Änderungen in Swift 4) siehe die zweite Anmerkung unten).

  • Auf die Methode file-private bar kann über dieselbe Quelldatei zugegriffen werden.

Hinweise:

  1. Der Vorschlag SE-0159 - Fix Private Access Levels schlug vor, auf die Swift 2 Semantik in Swift 4. Nach einer längeren Zeitspanne) zurückzukehren und kontroverse Diskussion über die Swift-Evolution-Mailingliste, war der Vorschlag abgelehnt .

  2. Der Vorschlag SE-0169 - Verbessern der Interaktion zwischen privaten Deklarationen und Erweiterungen schlägt vor, private Deklarationen in einem Typ für Erweiterungen desselben Typs zugänglich zu machen, wenn die Erweiterung in definiert ist. -same source file. Dieser Vorschlag wurde angenommen und implementiert in Swift 4.

274
Martin R

Ich zeichne nur ein Diagramm über private , fileprivate , offen und öffentlich

Ich hoffe, es kann Ihnen schnell helfen. Eine Beschreibung des Textes finden Sie in der Antwort von Martin R

[Update Swift 4]

enter image description here

77
Stephen Chen

Eine praktische Faustregel ist, dass Sie private für Variablen, Konstanten, innere Strukturen und Klassen verwenden, die nur in der Deklaration Ihrer Klasse/Struktur verwendet werden. Sie verwenden fileprivate für Dinge, die innerhalb Ihrer Erweiterungen innerhalb derselben Datei wie Ihre Klasse/Struktur, jedoch außerhalb ihrer definierten geschweiften Klammern (dh ihres lexikalischen Bereichs) verwendet werden.

    class ViewController: UIViewController {
        @IBOutlet var tableView: UITableView!
        //This is not used outside of class Viewcontroller
        private var titleText = "Demo"
        //This gets used in the extension
        fileprivate var list = [String]()
        override func viewDidLoad() {
            navigationItem.title = titleText
        }
    }

    extension ViewController: UITableViewDataSource {
        func numberOfSections(in tableView: UITableView) -> Int {
            return list.count
        }
    }
6
Josh Homann

In Swift 4.0 ist Private jetzt in der Erweiterung, aber in derselben Datei verfügbar. Wenn Sie die Erweiterung in einer anderen Datei deklarieren/definieren, ist Ihre private Variable für Ihre Erweiterung nicht verfügbar **

Datei privat
Der dateiprivate Zugriff beschränkt die Verwendung einer Entität auf ihre eigene definierende Quelldatei. Verwenden Sie den dateiprivaten Zugriff, um die Implementierungsdetails einer bestimmten Funktionalität auszublenden, wenn diese Details in einer gesamten Datei verwendet werden.
Syntax:fileprivate <var type> <variable name>
Beispiel:fileprivate class SomeFilePrivateClass {}


Privat
Privater Zugriff beschränkt die Verwendung einer Entität auf die beiliegende Deklaration und auf Erweiterungen dieser Deklaration, die sich in derselben Datei befinden . Verwenden Sie den privaten Zugriff, um die Implementierungsdetails einer bestimmten Funktionalität auszublenden, wenn diese Details nur in einer einzelnen Deklaration verwendet werden.
Syntax:private <var type> <variable name>
Beispiel:private class SomePrivateClass {}


Hier finden Sie weitere Details zu allen Zugriffsebenen: Swift - Access Levels

Schau dir diese Bilder an:
Datei: ViewController.Swift
Hier befinden sich die Erweiterung und der Ansichts-Controller in derselben Datei, daher kann auf die private Variable testPrivateAccessLevel in der Erweiterung zugegriffen werden

enter image description here


Datei: TestFile.Swift
Hier befinden sich die Erweiterung und der Ansichts-Controller in unterschiedlichen Dateien. Daher ist die private Variable testPrivateAccessLevel in der Erweiterung nicht verfügbar.

enter image description here

enter image description here


Hier Klasse ViewController2 ist eine Unterklasse von ViewController und beide befinden sich in derselben Datei. Hier kann nicht auf die private Variable testPrivateAccessLevel in der Unterklasse zugegriffen werden, sondern auf fileprivate in der Unterklasse.

enter image description here

6
Krunal

Obwohl die Antworten von @ MartinR und @ StephenChen perfekt sind, ändert Swift 4 die Dinge ein wenig.

Private wird jetzt als privat für eine Klasse betrachtet, in der es deklariert ist, sowie für seine Erweiterungen.

FilePrivate wird in dieser Datei als privat betrachtet, sei es eine Klasse, in der die Variable definiert ist, ihre Erweiterung oder andere Klassen, die in derselben Datei definiert sind.

5
Nikita P

Im folgenden Beispiel scheinen sich von private und fileprivate geänderte Sprachkonstrukte identisch zu verhalten:

fileprivate func fact(_ n: Int) -> Int {
    if (n == 0) {
        return 1
    } else {
        return n * fact(n - 1)
    }
}

private func gauss(_ n: Int) -> Int {
    if (n == 0) {
        return 0
    } else {
        return n + gauss(n - 1)
    }
}

print(fact(0))
print(fact(5))
print(fact(3))

print(gauss(10))
print(gauss(9))

Das liegt wohl an der Intuition. Aber gibt es eine Ausnahme?

Mit freundlichen Grüßen.

3
Tomas Balderas

Aktualisiert für Swift 5

Privat vs FilePrivate

Fügen Sie zur besseren Übersichtlichkeit das Code-Snippet in Playground ein

class Sum1 {
    let a: Int!
    let b: Int!
    private var result: Int?
    fileprivate var resultt: Int?

    init(a : Int, b: Int) {
        self.a = a
        self.b = b
    }

    func sum(){
        result = a + b
        print(result as! Int)
    }
}

let aObj = Sum1.init(a: 10, b: 20)
aObj.sum()
aObj.resultt //File Private Accessible as inside same Swift file
aObj.result //Private varaible will not be accessible outside its definition except extensions

extension Sum1{

    func testing() {

        // Both private and fileprivate accessible in extensions
        print(result)
        print(resultt)
    }
}

//If SUM2 class is created in same file as Sum1 ---
class Sum2{

    func test(){

        let aSum1 = Sum1.init(a: 2, b: 2)
        // Only file private accessible
        aSum1.resultt

    }
}

Hinweis: Außerhalb von Swift file sind sowohl private als auch fileprivate nicht zugänglich.

2
Arpit Jain

Dies ist die Erklärung für Swift 4. Für Swift 3 ist der Unterschied der private. Swift 3 kann nicht privat sein Auf die über ihre Erweiterung zugegriffen wird, kann nur Klasse A selbst zugreifen.

enter image description here Nach Swift 4 wird fileprivate etwas redundant, da die Person normalerweise die Unterklasse nicht in derselben Datei definiert. Private sollte in den meisten Fällen ausreichen.

2
Weidian Huang

filePrivate - Die Zugriffskontrollebene befindet sich in der Datei.

Fall 1: Wenn wir eine Erweiterung mit derselben Klassendatei erstellen und versuchen, auf die Funktion fileprivate oder die Eigenschaft fileprivate in ihrer Erweiterung zuzugreifen, ist der Zugriff zulässig
Fall 2: Wenn wir eine Klassenerweiterung in einer neuen Datei erstellen und jetzt versuchen, auf die Funktion fileprivate oder die Eigenschaft fileprivate zuzugreifen, ist der Zugriff nicht zulässig

privat - Die Zugriffskontrollebene befindet sich im lexikalischen Bereich

case 1: Wenn eine Eigenschaft oder Funktion in einer Klasse als privat deklariert ist, ist der Gültigkeitsbereich standardmäßig die Klasse. case 2: Wenn private Instanz mit in function body deklariert wird, ist der Gültigkeitsbereich der Instanz auf function body beschränkt.

2
Ashish Chhabra
class Privacy {

    fileprivate(set) var pu:Int {
        get {
            return self.pr
        }
        set {
            self.pr = newValue
        }
    }
    private var pr:Int = 0
    fileprivate var fp:Int = 0


    func ex() {
        print("\(self.pu) == \(self.pr) and not \(self.fp)")
    }
}


extension Privacy {

    func ex2() {
        self.pu = 5
        self.ex()
    }

}

Ich mag das, weil es für Ivars super einfach ist.

Versuchen Sie, fileprivate in private zu ändern (und umgekehrt) und sehen Sie, was beim Kompilieren passiert ...

1
CPD