Jaki jest dobry przykład, aby odróżnić fileprivate i private w Swift3
Ten artykuł był pomocny w zrozumieniu nowych specyfikacji dostępu w Swift 3
. Podaje również przykłady różnych zastosowań fileprivate
i private
.
Moje pytanie brzmi - czy użycie fileprivate
Na funkcji, która będzie używana tylko w tym pliku nie jest tym samym co użycie private
?
9 answers
fileprivate
jest tym, co private
było wcześniej
Wydania Swift: dostępne z
ten sam plik źródłowy. Deklaracja oznaczona jako private
może być teraz dostępna tylko w zakresie leksykalnym, w którym jest zadeklarowana.
Więc private
jest bardziej restrykcyjne niż fileprivate
.
Począwszy od Swift 4, prywatne deklaracje wewnątrz typu są dostępne dla rozszerzeń tego samego typu, jeśli rozszerzenie jest zdefiniowane w tym samym pliku źródłowym.
Przykład (wszystko w jednym źródle plik):
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()
Metoda private
foo
jest dostępna tylko w zakresie definicjaclass A { ... }
. Nie jest nawet dostępny z rozszerzenie do typu (w Swift 3, patrz druga uwaga poniżej zmiany w Swift 4).Metoda file-private
bar
jest dostępna z tego samego pliku źródłowego.
uwagi:
Propozycja SE-0159-Fix Private Access Levels sugerowała powrót do semantyka Swift 2 w języku Swift 4. Po długiej i kontrowersyjnej dyskusji na liście dyskusyjnej swift-evolution, propozycja została odrzucona.
Propozycja SE-0169-poprawa interakcji między prywatnymi deklaracjami i rozszerzeniami sugeruje, aby
private
deklaracje wewnątrz typu dostępnego dla rozszerzeń tego samego typu jeśli rozszerzenie jest zdefiniowane w tym samym pliku źródłowym. Propozycja ta została przyjęta i wdrożona w Swift 4.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-20 20:40:14
Rysuję diagram o prywatnych, fileprivate, open and public
Mam nadzieję, że szybko ci pomoże, opis tekstowy znajduje się w odpowiedzi Martina R
[ Update Swift 4 ]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 05:00:57
Praktyczna zasada jest taka, że używasz prywatnych dla zmiennych, stałych, wewnętrznych struktur i klas, które są używane tylko wewnątrz deklaracji twojej klasy / struktury. Używasz fileprivate dla rzeczy, które są używane wewnątrz twoich rozszerzeń w tym samym pliku co twoja klasa/struktura, ale poza ich definiującymi nawiasami klamrowymi(np. ich zakres leksykalny).
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
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 00:40:33
Chociaż odpowiedź @MartinR i @StephenChen są idealne, Swift 4 zmienia trochę rzeczy.
Private jest teraz uważane za prywatne dla klasy, w której jest zadeklarowana, a także dla jej rozszerzeń.
FilePrivate jest uważany za prywatny w tym Pliku, czy to klasa, w której zmienna jest zdefiniowana, jej rozszerzenie, czy jakiekolwiek inne klasy zdefiniowane w tym samym pliku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-13 08:33:08
W poniższym przykładzie konstrukcje językowe zmodyfikowane przez private
i fileprivate
wydają się zachowywać identycznie:
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))
To chyba według intuicji. Ale czy jest jakiś wyjątek?
Pozdrawiam serdecznie.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-21 06:20:03
W Swift 4.0, Private jest teraz dostępny w rozszerzeniu, ale w tym samym pliku. Jeśli zadeklarujesz / zdefiniujesz rozszerzenie w innym pliku, wtedy twoja prywatna zmienna nie będzie dostępna dla Twojego rozszerzenia * *
Plik Prywatny
File-private access ogranicza użycie encji do własnego definiującego pliku źródłowego. Użyj file-private access, aby ukryć szczegóły implementacji określonej funkcjonalności, gdy te szczegóły są używane w całym pliku.
składnia: fileprivate <var type> <variable name>
przykład: fileprivate class SomeFilePrivateClass {}
Private
Private access ogranicza użycie encji do załączającej deklaracji i rozszerzeń tej deklaracji, które znajdują się w tym samym pliku. Użyj dostępu prywatnego, aby ukryć szczegóły implementacji określonej funkcjonalności, gdy dane te są używane tylko w ramach jednej deklaracji.
składnia: private <var type> <variable name>
przykład: private class SomePrivateClass {}
Oto więcej szczegółów na temat wszystkie poziomy dostępu: Swift-poziomy dostępu
spójrz na to zdjęcie:
Plik: ViewController.swift
tutaj rozszerzenie i kontroler widoku znajdują się w tym samym pliku, stąd prywatna zmienna testPrivateAccessLevel
jest dostępna w rozszerzeniu
Plik: TestFile.swift
tutaj rozszerzenie i kontroler widoku znajdują się w różnych plikach, stąd prywatna zmienna testPrivateAccessLevel
nie jest dostępna w przedłużenie.
Klasa ViewController2
jest podklasą ViewController
i obie znajdują się w tym samym pliku. Tutaj zmienna prywatna testPrivateAccessLevel
nie jest dostępna w podklasie, ale fileprivate jest dostępna w podklasie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-09 13:54:09
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()
}
}
Podoba mi się to, ponieważ jest to bardzo proste dla ivars.
Spróbuj zmienić fileprivate na private (I vice versa) i zobacz co się stanie podczas kompilacji...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-20 22:26:04
FilePrivate - poziom kontroli dostępu znajduje się wewnątrz pliku.
Case 1: Jeżeli utworzymy rozszerzenie z plikiem w tej samej klasie i spróbujemy uzyskać dostęp do funkcji fileprivate lub właściwości fileprivate w jej rozszerzeniu-dostęp dozwolony
case 2: Jeżeli utworzymy rozszerzenie klasy w Nowym pliku - a teraz spróbujemy uzyskać dostęp do funkcji fileprivate lub właściwości fileprivate-access not allowed
Private - poziom kontroli dostępu jest z zakresu leksykalnego
Case 1: Jeżeli właściwość lub funkcja jest zadeklarowana jako prywatna w klasie - wtedy scope jest domyślnie klasą. przypadek 2 : jeśli instancja prywatna jest zadeklarowana z ciałem funkcji - wtedy zakres instancji jest ograniczony do ciała funkcji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-30 05:27:59
To jest wyjaśnienie dla swift 4. Dla swift 3 różnica jest prywatna. swift 3 private nie może być dostępny przez jego rozszerzenie, tylko sama Klasa A może uzyskać dostęp.
Po swift 4 fileprivate staje się nieco zbędny, ponieważ osoba normalnie nie zdefiniuje podklasy w tym samym pliku. Prywatne powinno wystarczyć w większości przypadków.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-22 04:15:07