Jak domyślnie ustawić publiczną inicjalizację elementu członkowskiego dla struktur w języku Swift?


164

Mam szybki framework, który definiuje strukturę:

public struct CollectionTO {
    var index: Order
    var title: String
    var description: String
}

Jednak wydaje mi się, że nie mogę użyć niejawnego inicjatora elementu członkowskiego z innego projektu, który importuje bibliotekę. Nie można zainicjować „CollectionTO”, ponieważ nie ma dostępnych inicjatorów. tj. nie przekazuje domyślnemu, niejawnemu inicjatorowi elementu wise, słowa kluczowego public.

var collection1 = CollectionTO(index: 1, title: "New Releases", description: "All the new releases")

Muszę dodać własną metodę init w następujący sposób:

public struct CollectionTO {
    var index: Order
    var title: String
    var description: String

    public init(index: Order, title: String, description: String) {
        self.index = index;
        self.title = title;
        self.description = description;
    }

}

... ale wolałbym nie, gdyby ktoś wiedział o innym sposobie?

Odpowiedzi:


268

Cytując instrukcję:

„Domyślne inicjatory składowe dla typów struktur Domyślny inicjator składowych dla typu struktury jest uważany za prywatny, jeśli którakolwiek z przechowywanych właściwości struktury jest prywatna. W przeciwnym razie inicjator ma wewnętrzny poziom dostępu.

Podobnie jak w przypadku powyższego domyślnego inicjatora, jeśli chcesz, aby typ struktury publicznej był inicjalizowany za pomocą inicjatora składowego, gdy jest używany w innym module, musisz samodzielnie dostarczyć publiczny inicjator elementu członkowskiego jako część definicji typu. "

Fragment z „Swift Programming Language” , sekcja „Access Control” .


288
Cóż, to denerwujące. :(
Dan Loewenherz

7
[ github.com/apple/swift-evolution/blob/master/propiments/… mówi: „Cytując Chrisa Lattnera: Domyślne zachowanie inicjatora członkostwa w Swift ma co najmniej następujące wady (IMO): 2) Kontrola dostępu + często inicjalizacja członkostwa wymaga samodzielnego wdrożenia ”. Więc może to tylko niedobór, który istnieje bez konkretnego powodu. Nie udało się znaleźć więcej odniesień na ten temat.
Jano

8
@DanLoewenherz Tak, to niewygodne. Uzasadnienie jest następujące: „Typ publiczny domyślnie ma członków wewnętrznych, a nie publicznych. Jeśli chcesz, aby członek typu był publiczny, musisz jawnie oznaczyć go jako taki. To wymaganie gwarantuje, że publicznie dostępny interfejs API dla typu jest czymś, co zdecydujesz się publikować, i pozwala uniknąć omyłkowego prezentowania wewnętrznego działania typu jako publicznego interfejsu API. ” Fragment z: Apple Inc. „Swift Programming Language”. iBooks. itun.es/gb/jEUH0.l
bandejapaisa

18
Dyrektywa kompilatora przydałaby się do przesłonięcia domyślnego zachowania i upublicznienia go.
bandejapaisa

9
Wewnętrzny to okropny wybór dla domyślnego, imo. Zasadniczo gwarantuje, że napotkasz nieoczekiwane problemy podczas pierwszego odwołania do modułu z zewnątrz. Dlaczego nie ustawić domyślnie wszystkiego na prywatne, abyśmy mogli od razu stwierdzić, kiedy coś nie ma odpowiedniego poziomu dostępu, a następnie zdecydować, czy powinno to być publiczne czy wewnętrzne?
devios1

72

Chociaż nie jest możliwe posiadanie domyślnego inicjatora składowego, przynajmniej możesz go szybko utworzyć, wykonując następujące czynności:

  1. Ustaw obiekt tymczasowo jako klasę zamiast struktury
  2. Zapisać
  3. Kliknij prawym przyciskiem myszy nazwę klasy i wybierz Refactor -> Generate Memberwise Initializer
  4. Zmień go z powrotem w strukturę

znakomity. nie mogę ci wystarczająco podziękować za obejście tego szybkiego braku
Anton Tropashko

1
Działa i motywuje do faktycznego korzystania z klas zamiast struktur youtube.com/watch?v=_V2sBURgUBI
Isaac Carol Weisberg

To super wskazówka !!
Peymankh

6
Począwszy od Xcode 11, możesz również użyć Generate Memberwise Initializer na strukturach!
Brock Batsell

Fantastyczny!!! To nie jest dobra odpowiedź, ale jest to bardzo dobra wskazówka! Bardzo mi pomogło!
GuiOS


1

Mamy teraz rubinowy klejnot 💎 do analizowania kompletnego pliku szybkiego modelu danych, wiersz po wierszu i dodawania publicznych modyfikatorów dostępu, publicznych domyślnych inicjatorów dla elementów członkowskich i innych rzeczy do oddzielnego automatycznie generowanego pliku wyjściowego szybkiego.

Ten klejnot nazywa się swift_republic

Sprawdź następującą dokumentację dotyczącą uruchomienia tego klejnotu:

https://github.com/mehul90/swift_republic


1
Niesamowite rozwiązanie !! Stworzyłem już opakowanie swift_republici działa dobrze.
Md Shahed Hossain
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.