web-dev-qa-db-fra.com

Quel est un bon exemple pour différencier le fichier privé de privé dans Swift3

Cet article a été utile pour comprendre les nouveaux spécificateurs d'accès dans Swift 3. Il donne également quelques exemples de différentes utilisations de fileprivate et private.

Ma question est la suivante: l’utilisation de fileprivate sur une fonction qui ne sera utilisée que dans ce fichier est-elle identique à l’utilisation de private?

133
Nikita P

fileprivate est maintenant ce que private était dans les versions précédentes Swift: accessibles à partir du même fichier source. Une déclaration marquée comme private est désormais accessible uniquement dans la portée lexicale dans laquelle elle est déclarée. Donc, private est plus restrictif que fileprivate.

À partir de Swift 4, les déclarations privées à l'intérieur d'un type sont accessibles aux extensions du même type si l'extension est définie dans le même fichier source.

Exemple (tout dans un fichier source):

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()
  • La méthode privée foo n'est accessible que dans le cadre de la définition de class A { ... }. Il n'est même pas accessible depuis une extension du type (dans Swift 3, voir la deuxième note ci-dessous pour connaître les modifications apportées dans Swift 4).

  • La méthode file-private bar est accessible à partir du même fichier source.

Notes:

  1. La proposition SE-0159 - Fixer les niveaux d’accès privé suggère de revenir à la sémantique Swift _ _ de Swift 4. Après une discussion longue et controversée sur le Swift liste de diffusion -evolution, la proposition était rejetée .

  2. La proposition SE-0169 - Améliorer l’interaction entre les déclarations privées et les extensions suggère de faire des déclarations private dans un type accessible à des extensions du même type si l’extension est définie dans même fichier source. Cette proposition a été acceptée et implémentée dans Swift 4.

274
Martin R

Je viens de dessiner un diagramme sur privé , fileprivate , ouvert et public

J'espère que cela pourra vous aider rapidement. Pour une description, veuillez vous reporter à la réponse de Martin R

[Mise à jour Swift 4]

enter image description here

77
Stephen Chen

En règle générale, vous utilisez private pour les variables, les constantes, les structures internes et les classes utilisées uniquement dans la déclaration de votre classe/structure. Vous utilisez fileprivate pour les éléments utilisés à l'intérieur de vos extensions dans le même fichier que votre classe/structure, mais en dehors de leurs accolades définissantes (c'est-à-dire leur portée lexicale).

    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

Dans Swift 4.0, Private est maintenant accessible en extension, mais dans le même fichier. Si vous déclarez/définissez une extension dans un autre fichier, votre variable privée ne sera pas accessible pour votre extension **

Fichier privé
L'accès privé au fichier restreint l'utilisation d'une entité à son propre fichier source de définition. Utilisez l'accès privé au fichier pour masquer les détails d'implémentation d'une fonctionnalité spécifique lorsque ces détails sont utilisés dans un fichier entier.
Syntaxe: fileprivate <var type> <variable name>
Exemple: fileprivate class SomeFilePrivateClass {}


Privé
L'accès privé restreint l'utilisation d'une entité à la déclaration englobante et aux extensions de cette déclaration qui se trouvent dans le même fichier . Utilisez l'accès privé pour masquer les détails d'implémentation d'une fonctionnalité spécifique lorsque ces détails ne sont utilisés que dans une seule déclaration.
Syntaxe: private <var type> <variable name>
Exemple: private class SomePrivateClass {}


Voici plus de détails sur tous les niveaux d’accès: Swift - Niveaux d’accès

Regardez ces images:
Fichier: ViewController.Swift
Ici, l'extension et le contrôleur de vue sont tous deux dans le même fichier, donc la variable privée testPrivateAccessLevel est accessible en extension

enter image description here


Fichier: TestFile.Swift
Ici, l'extension et le contrôleur de vue se trouvent tous deux dans des fichiers différents. La variable privée testPrivateAccessLevel n'est donc pas accessible en extension.

enter image description here

enter image description here


Ici, la classe ViewController2 est une sous-classe de ViewController et les deux sont dans le même fichier. Ici, la variable privée testPrivateAccessLevel n'est pas accessible dans la sous-classe mais le fichier privé est accessible dans la sous-classe.

enter image description here

6
Krunal

Bien que les réponses de @ MartinR et de StephenChen soient parfaites, Swift 4 change un peu les choses.

Private est maintenant considéré comme privé pour une classe dans laquelle il est déclaré ainsi que pour ses extensions.

FilePrivate est considéré comme privé dans ce fichier, qu'il s'agisse d'une classe dans laquelle la variable est définie, de son extension ou de toute autre classe définie dans ce même fichier.

5
Nikita P

Dans l'exemple suivant, les constructions de langage modifiées par private et fileprivate semblent se comporter de manière identique:

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))

C'est selon l'intuition, je suppose. Mais, y a-t-il une exception?

Meilleures salutations.

3
Tomas Balderas

Mise à jour pour Swift 5

Privé vs FilePrivate

Pour plus de clarté, collez le fragment de code dans Playground

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

    }
}

Note: En dehors du fichier Swift, les fichiers privé et privé de fichier ne sont pas accessibles.

2
Arpit Jain

C'est l'explication de Swift 4. Pour Swift 3, la différence est le privé. Swift 3 private n'est pas accessible par son extension, seule la classe A elle-même peut y accéder.

enter image description here Après Swift 4, le fichier privé devient un peu redondant car personne ne définit normalement la sous-classe dans le même fichier. Privé devrait suffire dans la plupart des cas.

2
Weidian Huang

filePrivate - le niveau de contrôle d'accès est dans le fichier.

cas 1: Si nous créons une extension avec dans le même fichier de classe et essayons d'accéder à la fonction fileprivate ou à la propriété fileprivate dans son extension - accès autorisé
cas 2: Si nous créons une extension de classe dans un nouveau fichier - Et maintenant, essayez d’accéder à une fonction fileprivate ou à une propriété fileprivate - accès non autorisé

privé - le niveau de contrôle d'accès est dans la portée lexicale

cas 1: Si la propriété ou la fonction est déclarée privée dans la classe, alors la portée est par défaut la classe. cas 2: si une instance privée est déclarée avec dans le corps de la fonction - la portée de l'instance est limitée au corps de la fonction.

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()
    }

}

J'aime ça parce que c'est super simple pour Ivars.

Essayez de changer fileprivate en privé (et vice versa) et voyez ce qui se passe lors de la compilation ...

1
CPD