ฉันจะทำให้ค่าเริ่มต้นสมาชิกแบบเริ่มต้นเป็นสาธารณะโดยค่าเริ่มต้นสำหรับ structs ใน Swift ได้อย่างไร


165

ฉันมีกรอบที่รวดเร็วที่กำหนดโครงสร้าง:

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

อย่างไรก็ตามฉันไม่สามารถใช้ initializer ที่ชาญฉลาดของสมาชิกโดยปริยายจากโครงการอื่นที่นำเข้าห้องสมุด ข้อผิดพลาดคือ 'CollectionTO' ไม่สามารถเริ่มต้นได้เนื่องจากไม่มี initialisers ที่สามารถเข้าถึงได้ นั่นคือมันไม่ได้ให้ค่าปริยายของสมาชิกเริ่มต้นที่ฉลาดโดยใช้คำสำคัญสาธารณะ

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

ฉันต้องเพิ่มวิธีการเริ่มต้นของตัวเองเช่น:

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

}

... แต่ฉันไม่ต้องการถ้ามีวิธีอื่นที่ใครจะรู้?

คำตอบ:


270

การอ้างอิงคู่มือ:

"ค่าเริ่มต้น Memberwise Initializers สำหรับประเภทโครงสร้างค่าเริ่มต้น Memberwise initializer สำหรับประเภทโครงสร้างถือว่าเป็นส่วนตัวหากคุณสมบัติที่เก็บไว้ของโครงสร้างใด ๆ เป็นส่วนตัวไม่เช่นนั้น initializer จะมีระดับการเข้าถึงภายใน

เช่นเดียวกับค่าเริ่มต้นเริ่มต้นด้านบนหากคุณต้องการให้โครงสร้างชนิดสาธารณะสามารถเริ่มต้นได้ด้วยค่าเริ่มต้น Memberwise เมื่อใช้ในโมดูลอื่นคุณจะต้องให้ค่าเริ่มต้นค่าสมาชิกแบบสมาชิกสาธารณะด้วยตัวเองเป็นส่วนหนึ่งของคำจำกัดความของประเภท "

ตัดตอนมาจาก"ความ Swift Programming Language"ส่วน"การควบคุมการเข้าถึง"


289
มันน่ารำคาญนะ :(
Dan Loewenherz

7
[ github.com/apple/swift-evolution/blob/master/proposals/…พูดว่า: "Quoting Chris Lattner: พฤติกรรมการเริ่มต้น initialwise แบบสมาชิกสมาชิกของ Swift มีข้อบกพร่องเหล่านี้อย่างน้อย (IMO): 2) การควบคุมการเข้าถึง + initwise สมาชิกมักจะ คุณต้องใช้มันด้วยตนเอง” ดังนั้นอาจเป็นเพียงการขาดซึ่งมีอยู่โดยไม่มีเหตุผลโดยเฉพาะ ไม่พบข้อมูลอ้างอิงเพิ่มเติมเกี่ยวกับสิ่งนี้
Jano

8
@DanLoewenherz ใช่มันไม่สะดวก เหตุผลคือ:“ ประเภทสาธารณะค่าเริ่มต้นที่จะมีสมาชิกภายในไม่ใช่สมาชิกสาธารณะ หากคุณต้องการให้สมาชิกประเภทเป็นสาธารณะคุณจะต้องทำเครื่องหมายอย่างชัดเจน ข้อกำหนดนี้ทำให้มั่นใจได้ว่า API สาธารณะสำหรับประเภทเป็นสิ่งที่คุณเลือกที่จะเผยแพร่และหลีกเลี่ยงการนำเสนอผลงานภายในของประเภทเป็น API สาธารณะโดยไม่ได้ตั้งใจ” ข้อความที่ตัดตอนมาจาก: Apple Inc. “ ภาษาการเขียนโปรแกรม Swift” iBooks itun.es/gb/jEUH0.l
bandejapaisa

18
คอมไพเลอร์คำสั่งจะดีเพื่อแทนที่พฤติกรรมเริ่มต้นและทำให้เป็นสาธารณะ
bandejapaisa

9
ภายในเป็นตัวเลือกที่แย่มากสำหรับการเริ่มต้น imo โดยพื้นฐานแล้วรับประกันได้ว่าคุณจะพบกับปัญหาที่ไม่คาดคิดเมื่ออ้างอิงโมดูลจากภายนอกเป็นครั้งแรก ทำไมไม่เริ่มต้นทุกอย่างเป็นส่วนตัวเพื่อให้เราสามารถบอกได้ทันทีเมื่อบางสิ่งไม่ได้รับระดับการเข้าถึงที่ถูกต้องแล้วตัดสินใจว่าควรเป็นสาธารณะหรือภายใน
devios1

72

แม้ว่าจะเป็นไปไม่ได้ที่จะมี initializer memberwise เริ่มต้นเป็นอย่างน้อยคุณสามารถทำอย่างรวดเร็วด้วยขั้นตอนต่อไปนี้:

  1. ทำให้วัตถุเป็นคลาสชั่วคราวแทน struct
  2. บันทึก
  3. คลิกขวาที่ชื่อคลาสและเลือก refactor -> สร้าง Memberwise Initializer
  4. เปลี่ยนกลับเป็นโครงสร้าง

ฉลาด ไม่สามารถขอบคุณมากพอที่จะหลีกเลี่ยงข้อบกพร่องที่รวดเร็วนี้
Anton Tropashko

1
ใช้งานได้และกระตุ้นให้ใช้คลาสจริงแทน structs youtube.com/watch?v=_V2sBURgUBI
Isaac Carol Weisberg

นั่นเป็นเคล็ดลับสุดยอด !!
Peymankh

6
ตั้งแต่วันที่ Xcode 11 คุณสามารถใช้สร้าง Memberwise Initializer บน struct ได้เช่นกัน!
Brock Batsell

มหัศจรรย์ !!! มันไม่ใช่คำตอบที่ถูกต้อง แต่เป็นคำแนะนำที่ดีมาก! ช่วยฉันมาก!
GuiOS

3

จนกว่า Apple จะเปลี่ยนสิ่งนี้และทำให้มันน่ารำคาญน้อยลงคุณสามารถใช้ https://github.com/Bouke/SwiftInitializerGenerator (หรืออื่น ๆ ) สิ่งนี้สำหรับการสร้างตัวเริ่มต้นสาธารณะ ดังนั้นมันจะทำงานน้อยลง พยายามและใช้งานได้ เวอร์ชั่น Xcode 10.0, เซียร์ราสูง 10.13.6


1

ตอนนี้เรามีอัญมณีทับทิม💎ในการแยกวิเคราะห์ไฟล์โมเดลข้อมูล swift ที่สมบูรณ์แบบทีละบรรทัดและเพิ่มตัวดัดแปลงการเข้าถึงสาธารณะตัวกำหนดค่าเริ่มต้นที่เป็นสมาชิกเริ่มต้นที่ชาญฉลาดของสาธารณะและสิ่งอื่น ๆ ลงในไฟล์ swift ที่สร้างขึ้นอัตโนมัติ

อัญมณีนี้เรียกว่าswift_republic

โปรดตรวจสอบเอกสารต่อไปนี้สำหรับการเรียกใช้อัญมณีนี้:

https://github.com/mehul90/swift_republic


1
ทางออกที่ยอดเยี่ยม !! ฉันสร้างเสื้อคลุมswift_republicและทำงานได้ดีอยู่แล้ว
Md Shahed Hossain
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.