Come posso rendere pubblico l'inizializzatore membro, per impostazione predefinita, per le strutture in Swift?


164

Ho un framework rapido che definisce una struttura:

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

Tuttavia, non riesco a usare l'inizializzatore saggio dei membri impliciti da un altro progetto che importa la libreria. L'errore è "CollectionTO" non può essere inizializzato perché non ha inizializzatori accessibili. cioè non sta dando la parola chiave pubblica all'inizialista saggio membro predefinito predefinito.

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

Devo aggiungere il mio metodo init in questo modo:

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;
    }

}

... ma preferirei di no se c'è un altro modo in cui qualcuno lo sa?

Risposte:


269

Citando il manuale:

"Inizializzatori Memberwise predefiniti per i tipi di struttura L'inizializzatore memberwise predefinito per un tipo di struttura è considerato privato se una delle proprietà memorizzate della struttura è privata. Altrimenti, l'inizializzatore ha un livello di accesso interno.

Come con l'inizializzatore predefinito sopra, se si desidera che un tipo di struttura pubblica sia inizializzabile con un inizializzatore membro, quando utilizzato in un altro modulo, è necessario fornire un inizializzatore membro membro come parte della definizione del tipo. "

Estratto da "Il linguaggio di programmazione Swift" , sezione "Controllo accessi" .


289
Bene, questo è fastidioso. :(
Dan Loewenherz,

7
[ github.com/apple/swift-evolution/blob/master/proposals/… dice: “Citando Chris Lattner: il comportamento predefinito di inizializzazione membro di Swift ha almeno queste carenze (IMO): 2) Controllo accessi + init membro spesso richiede di implementarlo da soli ”. Quindi forse è solo una carenza che esiste senza motivo in particolare. Impossibile trovare ulteriori riferimenti al riguardo.
Jano,

8
@DanLoewenherz Sì, è scomodo. La logica è: “Un tipo pubblico ha come impostazione predefinita i membri interni, non i membri pubblici. Se si desidera che un membro del tipo sia pubblico, è necessario contrassegnarlo esplicitamente come tale. Questo requisito garantisce che l'API per un tipo rivolta al pubblico sia qualcosa che tu accetti alla pubblicazione ed evita di presentare per errore i meccanismi interni di un tipo come API pubblica. " Estratto da: Apple Inc. "The Swift Programming Language". iBook. itun.es/gb/jEUH0.l
bandejapaisa,

18
Una direttiva del compilatore sarebbe utile per sovrascrivere il comportamento predefinito e renderlo pubblico.
bandejapaisa,

9
Interno è una scelta terribile per un valore predefinito, imo. Fondamentalmente garantisce che si verificheranno problemi imprevisti quando si fa riferimento a un modulo esternamente per la prima volta. Perché non impostare tutto come privato, in modo da poter dire immediatamente quando qualcosa non ha il livello di accesso corretto e quindi decidere se dovrebbe essere pubblico o interno?
devios1

72

Sebbene non sia possibile avere l'inizializzatore memberwise predefinito, almeno puoi eseguirne uno rapidamente con i seguenti passaggi:

  1. Rende l'oggetto temporaneamente una classe invece di una struttura
  2. Salva
  3. Fare clic con il tasto destro del mouse sul nome della classe e selezionare refactor -> Genera inizializzatore Memberwise
  4. Riportalo in uno struct

brillante. non posso ringraziarvi abbastanza per aggirare questa rapida carenza
Anton Tropashko,

1
Funziona e motiva anche a utilizzare effettivamente le classi anziché le strutture youtube.com/watch?v=_V2sBURgUBI
Isaac Carol Weisberg,

È un consiglio super !!
Peymankh,

6
A partire da Xcode 11, puoi anche usare Generate Memberwise Initializer su struct!
Brock Batsell,

Fantastico!!! Non è la risposta giusta, ma è un ottimo consiglio! Mi ha aiutato molto!
GuiOS


1

Ora abbiamo un gioiello rubino 💎 per analizzare un file di modello di dati rapido completo, riga per riga e aggiungere modificatori di accesso pubblico, inizializzatori predefiniti in base ai membri pubblici e altre cose in un file rapido di output generato automaticamente separato.

Questa gemma si chiama swift_republic

Si prega di consultare la seguente documentazione per l'esecuzione di questo gioiello:

https://github.com/mehul90/swift_republic


1
Ottima soluzione !! Ho già creato un wrapper per swift_republice funziona benissimo.
Md Shahed Hossain,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.