Quel est un bon exemple pour différencier fichier privé et privé dans Swift3
142
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 fileprivateet private.
Ma question est la suivante: l'utilisation fileprivated'une fonction qui ne sera utilisée que dans ce fichier n'est-elle pas la même que l'utilisation private?
fileprivateest maintenant ce privatequi était dans les versions précédentes de Swift: accessible à partir du même fichier source. Une déclaration marquée comme privaten'est désormais accessible que dans la portée lexicale dans laquelle elle est déclarée. C'est donc privateplus restrictif que fileprivate.
Depuis 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 (le tout dans un seul fichier source):
class A {privatefunc foo(){}fileprivatefunc 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 méthode n'est accessible que dans le cadre de la class A { ... }définition. Il n'est même pas accessible depuis une extension du type (dans Swift 3, voir la deuxième note ci-dessous pour les changements dans Swift 4).
Le fichier privé bar méthode de est accessible à partir du même fichier source.
Remarques:
La proposition SE-0159 - Fixer les niveaux d'accès privé suggérait 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 était rejetée .
Si vous convertissez automatiquement le code de Swift 2 en 3, Xcode se transformera privateen fileprivate. Cependant, si vous avez le luxe de le faire à la main, vous pouvez souvent profiter de partir privatecomme private... si ça compile, tout va bien.
Dan Rosenstark
@DanielLarsson: Concernant vos suggestions de modification: les deux commentaires s'appliquent à l' foo()appel.
Martin R
82
Je viens de dessiner un diagramme sur privé , fichier privé , ouvert et public
J'espère que cela pourra vous aider rapidement, pour la description du texte, veuillez vous référer à la réponse de Martin R.
attention, fileprivaten'est pas lié à l'extension mais au fichier (écrire une extension de classe A dans un autre fichier ne permettra pas l'utilisation de fileprivatemembres)
Vince
1
Cela semble incorrect. Vous manquez le point clé. Vous devez faire la différence entre les classes qui sont à l'intérieur du même module et qui sont dans des modules différents. S'ils sont dans des modules différents, publiccela ne vous permettra pas d'hériter, donc la 3ème image est incorrecte. De plus, vous pouvez toujours ajouter 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.
Sulthan
En effet, je dois mentionner que mon schéma ne fonctionne que sur le même module, donc la 3ème image je veux juste que l'utilisateur comprenne rapidement fileprivate ne fonctionne que sur le même fichier.
Stephen Chen
6
Une règle pratique est que vous utilisez private pour les variables, les constantes, les structures internes et les classes qui ne sont utilisées que dans 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 définissant (ie. Leur portée lexicale).
classViewController:UIViewController{@IBOutletvar tableView:UITableView!//This is not used outside of class Viewcontroller
privatevar titleText ="Demo"//This gets used in the extension
fileprivatevar list =[String]()overridefunc viewDidLoad(){
navigationItem.title = titleText
}}extensionViewController:UITableViewDataSource{func numberOfSections(in tableView:UITableView)->Int{return list.count
}}
Dans Swift 4.0, Private est désormais 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 à votre extension **
L' accès au fichier privé au fichier privé limite l'utilisation d'une entité à son propre fichier source de définition. Utilisez l'accès privé de 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é limite 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 {}
Regardez ces images: File: ViewController.swift
Ici l'extension et le contrôleur de vue sont tous deux dans le même fichier, donc la variable privée testPrivateAccessLevelest accessible en extension
File: TestFile.swift
Ici, l'extension et le contrôleur de vue sont tous deux dans des fichiers différents, donc la variable privée testPrivateAccessLeveln'est pas accessible en extension.
Ici, la classe ViewController2est une sous-classe de ViewControlleret les deux sont dans le même fichier. Ici, la variable privée testPrivateAccessLeveln'est pas accessible dans la sous-classe mais fileprivate est accessible dans la sous-classe.
Bien que les réponses de @ MartinR et @ StephenChen soient parfaites, Swift 4 change un peu les choses.
Privé est désormais 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.
Pour plus de clarté, collez l'extrait de code dans Playground
classSum1{let a:Int!let b:Int!privatevar result:Int?fileprivatevar 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
extensionSum1{func testing(){// Both private and fileprivate accessible in extensions
print(result)
print(resultt)}}//If SUM2 class is created in same file as Sum1 ---
classSum2{func test(){let aSum1=Sum1.init(a:2, b:2)// Only file private accessible
aSum1.resultt
}}
Remarque : en dehors du fichier Swift, les fichiers private et fileprivate ne sont pas accessibles.
filePrivate - le niveau de contrôle d'accès se trouve 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 essayons d'accéder à la fonction fileprivate ou fileprivate propriété - accès non autorisé
privé - le niveau de contrôle d'accès est à portée lexicale
cas 1 : Si la propriété ou la fonction est déclarée comme privée dans la classe, 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 - alors la portée de l'instance est limitée au corps de la fonction.
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.
Après swift 4, fileprivate devient un peu redondant, car normalement personne ne définira la sous-classe dans le même fichier. Privé devrait suffire dans la plupart des cas.
private
enfileprivate
. Cependant, si vous avez le luxe de le faire à la main, vous pouvez souvent profiter de partirprivate
commeprivate
... si ça compile, tout va bien.foo()
appel.Je viens de dessiner un diagramme sur privé , fichier privé , ouvert et public
J'espère que cela pourra vous aider rapidement, pour la description du texte, veuillez vous référer à la réponse de Martin R.
[Mettre à jour Swift 4]
la source
fileprivate
n'est pas lié à l'extension mais au fichier (écrire une extension de classe A dans un autre fichier ne permettra pas l'utilisation defileprivate
membres)public
cela ne vous permettra pas d'hériter, donc la 3ème image est incorrecte. De plus, vous pouvez toujours ajouter 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.Une règle pratique est que vous utilisez private pour les variables, les constantes, les structures internes et les classes qui ne sont utilisées que dans 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 définissant (ie. Leur portée lexicale).
la source
Dans Swift 4.0, Private est désormais 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 à votre extension **
L'
accès au fichier privé au fichier privé limite l'utilisation d'une entité à son propre fichier source de définition. Utilisez l'accès privé de 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é limite 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:
File: 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 extensionFile: TestFile.swift
Ici, l'extension et le contrôleur de vue sont tous deux dans des fichiers différents, donc la variable privée
testPrivateAccessLevel
n'est pas accessible en extension.Ici, la classe
ViewController2
est une sous-classe deViewController
et les deux sont dans le même fichier. Ici, la variable privéetestPrivateAccessLevel
n'est pas accessible dans la sous-classe mais fileprivate est accessible dans la sous-classe.la source
Bien que les réponses de @ MartinR et @ StephenChen soient parfaites, Swift 4 change un peu les choses.
Privé est désormais 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.
la source
Mis à jour pour Swift 5
Privé vs FilePrivate
Pour plus de clarté, collez l'extrait de code dans Playground
Remarque : en dehors du fichier Swift, les fichiers private et fileprivate ne sont pas accessibles.
la source
filePrivate - le niveau de contrôle d'accès se trouve 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 essayons d'accéder à la fonction fileprivate ou fileprivate propriété - accès non autorisé
privé - le niveau de contrôle d'accès est à portée lexicale
cas 1 : Si la propriété ou la fonction est déclarée comme privée dans la classe, 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 - alors la portée de l'instance est limitée au corps de la fonction.
la source
Dans l'exemple suivant, les constructions de langage modifiées par
private
etfileprivate
semblent se comporter de la même manière:C'est selon l'intuition, je suppose. Mais y a-t-il une exception?
Meilleures salutations.
la source
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.
Après swift 4, fileprivate devient un peu redondant, car normalement personne ne définira la sous-classe dans le même fichier. Privé devrait suffire dans la plupart des cas.
la source
J'aime ça parce que c'est super simple pour les ivars.
Essayez de changer fileprivate en private (et vice versa) et voyez ce qui se passe lors de la compilation ...
la source