148 votes

Quel est un bon exemple pour faire la différence entre fileprivate et private en Swift3

Ce site article a été utile pour comprendre les nouveaux spécificateurs d'accès de l'application Swift 3 . Il donne également quelques exemples de différentes utilisations de fileprivate y private .

Ma question est la suivante : est-ce qu'utiliser fileprivate sur une fonction qui ne sera utilisée que dans ce fichier, ce qui revient à utiliser private ?

288voto

Martin R Points 105727

fileprivate est maintenant ce que private était dans les versions précédentes versions précédentes de Swift : accessibles à partir le même fichier source. Une déclaration marquée comme private ne peut maintenant être accédé qu'à l'intérieur de la portée lexicale dans laquelle il est déclaré. Ainsi, private est plus restrictive que fileprivate .

A 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 seul 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()
  • Le privé foo n'est accessible que dans le cadre de l'adresse class A { ... } définition. Elle n'est même pas accessible depuis une extension du type (dans Swift 3, voir la deuxième note ci-dessous pour les pour les changements dans Swift 4).

  • Le fichier-privé bar est accessible à partir du même fichier source.

Notes :

  1. La proposition SE-0159 - Correction des niveaux d'accès privés suggéré de revenir à la sémantique de Swift 2 dans Swift 4. Après une discussion longue et controversée sur la liste de diffusion swift-evolution, la proposition a été acceptée. rejeté .

  2. La proposition SE-0169 - Améliorer l'interaction entre les déclarations privées et les extensions suggère de faire private les déclarations à l'intérieur d'un type accessibles aux extensions du même type si l'extension est définie dans le même fichier source. Cette proposition a été acceptée et mise en œuvre dans Swift 4.

2 votes

Si vous convertissez automatiquement du code de Swift 2 à 3, Xcode transformera le code de Swift 2 en code de Swift 3. private en fileprivate . Cependant, si vous avez le luxe de le faire à la main, vous pouvez souvent bénéficier de laisser private como private ... s'il compile, tout va bien.

0 votes

@DanielLarsson : Re vos suggestions d'édition : Les deux sites les commentaires s'appliquent à la foo() appeler.

0 votes

Meilleur exemple Merci ! !

85voto

Stephen Chen Points 1939

Je dessine juste un diagramme sur privé , fichierprivé , ouvrir y public

Nous espérons qu'il pourra vous aider rapidement. Pour la description du texte, veuillez vous référer au site suivant Martin R Réponse de la Commission

[ Mise à jour Swift 4, 5 ]

enter image description here

9 votes

Attention, fileprivate n'est pas lié à l'extension mais au fichier (écrire une extension de classe A dans un autre fichier ne permettra pas d'utiliser l'option fileprivate membres)

1 votes

Cela semble incorrect. Vous oubliez le point essentiel. Vous devez faire la différence entre les classes qui se trouvent dans le même module et celles qui se trouvent dans des modules différents. Si elles se trouvent dans des modules différents, alors public ne vous permet pas d'hériter, donc la troisième image est incorrecte. De plus, vous pouvez toujours mettre une extension à n'importe quelle classe si vous pouvez la voir. Expliquer la visibilité sur les extensions n'est donc pas une très bonne idée.

0 votes

En effet, je dois préciser que mon diagramme ne fonctionne que sur le même module, donc la 3ème image que je veux juste que l'utilisateur comprenne rapidement. fichierprivé ne fonctionne que sur le même fichier.

6voto

Josh Homann Points 7888

Une règle pratique consiste à utiliser private pour les variables, les constantes, les structures internes et les classes qui ne sont utilisées qu'à l'intérieur de la déclaration de votre classe/structure. Vous utilisez fileprivate pour les choses qui sont utilisées à l'intérieur de vos extensions, dans le même fichier que votre classe/structure, mais en dehors de leurs accolades de définition (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
        }
    }

5voto

Nikita P Points 2390

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

Privé est maintenant considéré comme privé pour la classe dans laquelle il est déclaré et aussi pour ses extensions.

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

3voto

Tomas Balderas Points 31

Dans l'exemple suivant, les constructions linguistiques modifiées par private y 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 ?

Cordialement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X