Bagaimana saya bisa membuat initialiser memberwise menjadi publik, secara default, untuk struct di Swift?

164

Saya memiliki kerangka kerja cepat yang mendefinisikan struct:

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

Namun, sepertinya saya tidak dapat menggunakan penginisialisasi bijak anggota implisit dari proyek lain yang mengimpor perpustakaan. Kesalahannya adalah 'CollectionTO' tidak dapat diinisialisasi karena tidak memiliki inisialisasi yang dapat diakses. yaitu itu tidak memberikan default implisit anggota bijaksana menginisialisasi kata kunci publik.

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

Saya harus menambahkan metode init saya sendiri seperti ini:

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

}

... tapi saya lebih suka tidak jika ada cara lain ada yang tahu?

bandejapaisa
sumber

Jawaban:

268

Mengutip manual:

"Penginisialisasi Keanggotaan Anggota Default untuk Tipe Struktur Penginisialisasi memberwise standar untuk tipe struktur dianggap pribadi jika salah satu properti yang disimpan dalam struktur bersifat pribadi. Jika tidak, initializer memiliki tingkat akses internal.

Seperti halnya penginisialisasi default di atas, jika Anda ingin jenis struktur publik dapat diinisialisasi dengan penginisialisasi anggota ketika digunakan dalam modul lain, Anda harus menyediakan penginisialisasi anggota publik sendiri sebagai bagian dari definisi jenis. "

Kutipan dari "Bahasa Pemrograman Swift" , bagian "Kontrol Akses" .

bandejapaisa
sumber
288
Yah, itu menyebalkan. :(
Dan Loewenherz
7
[ github.com/apple/swift-evolution/blob/master/proposals/… mengatakan: “Mengutip Chris Lattner: Perilaku penginisialisasi yang berlaku bagi anggota Swift setidaknya memiliki kekurangan ini (IMO): 2) Kontrol akses + sering kali anggota tidak berpartisipasi mengharuskan Anda untuk mengimplementasikannya sendiri ”. Jadi mungkin itu hanya kekurangan yang ada tanpa alasan khusus. Tidak dapat menemukan lebih banyak referensi tentang ini.
Jano
8
@ DanLoewenherz Ya itu tidak nyaman. Alasannya adalah: “Tipe publik default untuk memiliki anggota internal, bukan anggota publik. Jika Anda ingin anggota tipe publik, Anda harus secara eksplisit menandainya sebagai anggota. Persyaratan ini memastikan bahwa API yang menghadap publik untuk suatu jenis adalah sesuatu yang Anda pilih untuk diterbitkan, dan menghindari penyajian kerja internal suatu jenis sebagai API publik secara tidak sengaja. " Kutipan dari: Apple Inc. “Bahasa Pemrograman Swift.” iBooks. itun.es/gb/jEUH0.l
bandejapaisa
18
Arahan kompiler akan bagus untuk mengesampingkan perilaku default, dan menjadikannya publik.
bandejapaisa
9
Internal adalah pilihan yang buruk untuk default, imo. Ini pada dasarnya menjamin bahwa Anda akan mengalami masalah yang tidak terduga ketika merujuk modul secara eksternal untuk pertama kalinya. Mengapa tidak default semuanya menjadi pribadi, sehingga kita dapat segera tahu ketika sesuatu tidak diberi tingkat akses yang benar dan kemudian memutuskan apakah itu harus publik atau internal?
devios1
72

Meskipun tidak mungkin untuk memiliki initializer bijaksana anggota standar setidaknya Anda dapat membuatnya dengan cepat dengan langkah-langkah berikut:

  1. Jadikan objek sebagai kelas sementara alih-alih struct
  2. Menyimpan
  3. Klik kanan nama kelas dan pilih refactor -> Hasilkan Inisialisasi Memberwise
  4. Ubah kembali ke struct
JP Aquino
sumber
cemerlang. tidak bisa cukup berterima kasih untuk mengatasi kekurangan yang cepat ini
Anton Tropashko
1
Bekerja dan juga memotivasi untuk benar-benar menggunakan kelas alih-alih struct youtube.com/watch?v=_V2sBURgUBI
Isaac Carol Weisberg
Itu tip yang super !!
Peymankh
6
Pada Xcode 11, Anda dapat menggunakan Generate Inisialisasi Memberwise pada struct juga!
Brock Batsell
Fantastis!!! Ini bukan jawaban yang tepat, tetapi merupakan tip yang sangat bagus! Banyak membantu saya!
GuiOS
3

Sampai Apple mengubahnya dan membuatnya tidak terlalu mengganggu, Anda dapat menggunakan https://github.com/Bouke/SwiftInitializerGenerator (atau lainnya) hal ini untuk pembuatan inisialisasi publik. Jadi itu akan kurang bekerja. Mencobanya dan berhasil. Xcode Versi 10.0, High Sierra 10.13.6

Zaporozhchenko Oleksandr
sumber
1

Kami sekarang memiliki permata ruby ​​💎 untuk mem-parsing file model data cepat lengkap, baris demi baris, dan menambahkan pengubah akses publik, penginisialisasi default anggota publik, dan hal-hal lain ke dalam file swift output otomatis yang dihasilkan secara otomatis.

Permata ini disebut swift_republic

Silakan periksa dokumentasi berikut untuk menjalankan permata ini:

https://github.com/mehul90/swift_republic

Mehul Parmar
sumber
1
Solusi luar biasa !! Saya sudah membuat pembungkus untuk swift_republicdan berfungsi dengan baik.
Md Shahed Hossain