Theo mặc định, làm cách nào tôi có thể công khai trình khởi chạy thành viên cho các cấu trúc trong Swift?


164

Tôi có một khung nhanh chóng xác định một cấu trúc:

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

Tuy nhiên, tôi dường như không thể sử dụng trình khởi tạo khôn ngoan thành viên ngầm từ một dự án khác nhập thư viện. Lỗi là 'CollectionTO' không thể được khởi chạy do không có trình khởi chạy có thể truy cập. tức là nó không cung cấp cho thành viên mặc định khởi tạo khôn ngoan mặc định từ khóa công khai.

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

Tôi phải thêm phương thức init của riêng mình như vậy:

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

}

... nhưng tôi không muốn nếu có một cách khác bất cứ ai biết?

Câu trả lời:


268

Trích dẫn hướng dẫn sử dụng:

"Bộ khởi tạo thành viên mặc định cho các loại cấu trúc Trình khởi tạo mặc định thành viên cho loại cấu trúc được coi là riêng tư nếu bất kỳ thuộc tính được lưu trữ nào của cấu trúc là riêng tư. Mặt khác, bộ khởi tạo có mức truy cập bên trong.

Như với trình khởi tạo mặc định ở trên, nếu bạn muốn loại cấu trúc công khai có thể khởi tạo được với trình khởi tạo thành viên khi được sử dụng trong mô-đun khác, bạn phải tự cung cấp trình khởi tạo thành viên công khai như một phần của định nghĩa kiểu. "

Trích từ "Ngôn ngữ lập trình Swift" , phần "Kiểm soát truy cập" .


288
Chà, thật khó chịu. :(
Dan Loewenherz

7
[ Github.com/apple/swift-evolution/blob/master/proposals/... nói: “Trích dẫn Chris Lattner: Các ngầm định initializer hành vi của Swift có ít nhất những thiếu sót (IMO): 2) Kiểm soát truy cập + các memberwise init thường đòi hỏi bạn phải tự thực hiện nó. Vì vậy, có lẽ nó chỉ là một thiếu sót mà không có lý do cụ thể. Không thể tìm thấy thêm tài liệu tham khảo về điều này.
Jano

8
@DanLoewenherz Có bất tiện. Lý do là: Một loại công khai mặc định có thành viên nội bộ, không phải thành viên công cộng. Nếu bạn muốn một thành viên loại được công khai, bạn phải đánh dấu rõ ràng như vậy. Yêu cầu này đảm bảo rằng API đối mặt với công khai cho một loại là thứ bạn chọn để xuất bản và tránh trình bày các hoạt động nội bộ của một loại là API công khai do nhầm lẫn. Trích từ: Apple Inc., Ngôn ngữ lập trình Swift. Sách điện tử. itun.es/gb/jEUH0.l
bandejapaisa

18
Một lệnh biên dịch sẽ là tốt để ghi đè hành vi mặc định và làm cho nó công khai.
bandejapaisa

9
Nội bộ là một lựa chọn khủng khiếp cho một mặc định, imo. Về cơ bản, nó đảm bảo rằng bạn sẽ gặp phải sự cố không mong muốn khi tham chiếu mô-đun bên ngoài lần đầu tiên. Tại sao không mặc định mọi thứ là riêng tư, để chúng tôi có thể nói ngay lập tức khi một cái gì đó không được cấp chính xác truy cập và sau đó quyết định xem nó nên công khai hay nội bộ?
devios1

72

Mặc dù không thể có trình khởi tạo thành viên mặc định, ít nhất bạn có thể thực hiện nhanh chóng với các bước sau:

  1. Làm cho đối tượng một lớp tạm thời thay vì một cấu trúc
  2. Tiết kiệm
  3. Nhấp chuột phải vào tên lớp và chọn refactor -> Tạo Trình khởi tạo thành viên
  4. Thay đổi nó trở lại một cấu trúc

xuất sắc. không thể cảm ơn bạn đủ để khắc phục sự thiếu hụt nhanh chóng này
Anton Tropashko

1
Hoạt động và cũng thúc đẩy để thực sự sử dụng các lớp thay vì cấu trúc youtube.com/watch?v=_V2sburgUBI
Isaac Carol Weisberg

Đó là một siêu mẹo !!
Peymankh

6
Kể từ Xcode 11, bạn cũng có thể sử dụng Tạo bộ khởi tạo thành viên trên các cấu trúc!
Brock Batsell

Tuyệt diệu!!! Đó không phải là câu trả lời đúng, nhưng là một mẹo rất hay! Đã giúp tôi rất nhiều!
GuiOS

3

Cho đến khi Apple thay đổi điều này và làm cho nó bớt khó chịu hơn, bạn có thể sử dụng https://github.com/Bouke/SwiftInitializerGenerator (hoặc bất kỳ thứ gì khác) để tạo công cụ khởi tạo công khai. Vì vậy, nó sẽ được làm việc ít hơn. Đã thử nó và nó hoạt động. Phiên bản Xcode 10.0, High Sierra 10.13.6


1

Bây giờ chúng ta có một viên ngọc ruby ​​để phân tích một tệp mô hình dữ liệu swift hoàn chỉnh, từng dòng một và thêm các sửa đổi truy cập công cộng, các trình khởi tạo mặc định thành viên công khai và những thứ khác vào một tệp swift đầu ra được tạo tự động riêng biệt.

Viên ngọc này được gọi là swift_Vpublic

Vui lòng kiểm tra các tài liệu sau đây để chạy đá quý này:

https://github.com/mehul90/swift_Vpublic


1
Giải pháp tuyệt vời !! Tôi đã tạo một trình bao bọc cho swift_republicvà hoạt động tốt.
Md Shahed Hossain
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.