W Swift poziomy dostępu (private, fileprivate, internal, public, open) wpływają nie tylko na klasy, struktury i ich właściwości, ale także na zagnieżdżone (nested) typy. Zagnieżdżony typ domyślnie dziedziczy poziom dostępu swojego otaczającego typu, chyba że podano inne, wyraźne ograniczenie.
Główne niuanse:
internal, zagnieżdżony typ nie może być bardziej otwarty niż zewnętrzny, ale może być bardziej „zamknięty” (na przykład zewnętrzny - public, zagnieżdżony - private).internal nie będą widoczne z innych modułów.Przykład:
public class A { public struct B { fileprivate func foo() {} } }
W tym przykładzie A i B są publiczne, ale metoda foo() jest plik-prywatna.
Pytanie: "Czy zagnieżdżony typ może mieć poziom dostępu wyższy niż otaczający go typ?"
Odpowiedź: Nie, poziom dostępu zagnieżdżonego typu nie może przekroczyć poziomu dostępu jego otaczającego typu. Próba zadeklarowania zagnieżdżonego typu z wyższym poziomem dostępu spowoduje błąd kompilatora.
Przykład błędu:
internal struct MyStruct { public enum MyEnum { ... } // Błąd: public nie może być wewnątrz internal }
Historia 1
W ogólnym frameworku poziomy dostępu zagnieżdżonych struktur nie były zsynchronizowane z zewnętrznymi typami. W wersji wydania doprowadziło to do niemożności używania wewnętrznych enum w aplikacji klienckiej i wymagało pilnej zmiany interfejsu.
Historia 2
W dużym projekcie wewnętrzny obiekt serwisowy miał zagnieżdżoną klasę ze statusami, zadeklarowaną jako internal. Po pojawieniu się nowego modułu, zależnego od tej klasy, integracja okazała się niemożliwa bez podniesienia poziomu dostępu i pełnej rekompilacji SDK.
Historia 3
W skomplikowanej bibliotece część zagnieżdżonych struktur była deklarowana jako public, a sam kontener jako internal. Podczas migracji do nowej wersji wystąpiły krytyczne błędy: publiczne typy nie kompilowały się w kontekście zewnętrznym, co utrudniło aktualizację wielu zespołów.