มีวิธีที่เร็วกว่า / สั้นกว่าในการเริ่มต้นตัวแปรในโครงสร้างสนิมหรือไม่?


106

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

มีวิธีที่รวบรัดกว่านี้หรือไม่?

struct cParams {
    iInsertMax: i64,
    iUpdateMax: i64,
    iDeleteMax: i64,
    iInstanceMax: i64,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

impl cParams {
    fn new() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}

คำตอบ:


169

คุณสามารถระบุค่าเริ่มต้นสำหรับโครงสร้างของคุณได้โดยใช้Defaultลักษณะ defaultฟังก์ชั่นจะมีลักษณะเช่นปัจจุบันของคุณnewฟังก์ชั่น:

impl Default for cParams {
    fn default() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}

จากนั้นคุณสามารถสร้างอินสแตนซ์ของโครงสร้างโดยให้เฉพาะค่าที่ไม่ใช่ค่าเริ่มต้น:

let p = cParams { iInsertMax: 10, ..Default::default() };

ด้วยการเปลี่ยนแปลงเล็กน้อยในโครงสร้างข้อมูลของคุณคุณสามารถใช้ประโยชน์จากการใช้งานเริ่มต้นที่ได้รับมาโดยอัตโนมัติ หากคุณใช้#[derive(Default)]กับโครงสร้างข้อมูลคอมไพลเลอร์จะสร้างฟังก์ชันเริ่มต้นให้คุณโดยอัตโนมัติโดยเติมแต่ละฟิลด์ด้วยค่าเริ่มต้น ค่าบูลีนดีฟอลต์เป็นเท็จค่าปริพันธ์เริ่มต้นคือ 0

ค่าเริ่มต้นของจำนวนเต็มเป็น 0 เป็นปัญหาที่นี่เนื่องจากคุณต้องการให้ฟิลด์จำนวนเต็มเป็น -1 โดยค่าเริ่มต้น คุณสามารถกำหนดประเภทใหม่ที่ใช้ค่าเริ่มต้นเป็น -1 และใช้แทนi64ในโครงสร้างของคุณ (ฉันยังไม่ได้ทดสอบ แต่ควรใช้งานได้)

แต่ผมขอแนะนำให้มีการเปลี่ยนแปลงเล็กน้อยโครงสร้างข้อมูลของคุณและใช้แทนOption<i64> i64ฉันไม่รู้บริบทของโค้ดของคุณ แต่ดูเหมือนว่าคุณกำลังใช้ค่าพิเศษ -1 เพื่อแทนความหมายพิเศษ "ไม่มีที่สิ้นสุด" หรือ "ไม่มีสูงสุด" ใน Rust เราใช้Optionเพื่อแสดงมูลค่าปัจจุบันที่เป็นทางเลือก ไม่จำเป็นต้องแฮ็ค -1 ตัวเลือกสามารถเป็นได้NoneหรือSome(x)โดยที่ x จะเป็นของคุณi64ที่นี่ มันอาจเป็นจำนวนเต็มที่ไม่ได้ลงชื่อถ้า -1 เป็นค่าลบเพียงอย่างเดียว ค่าเริ่มต้นOptionคือNoneดังนั้นด้วยการเปลี่ยนแปลงที่เสนอรหัสของคุณอาจมีลักษณะดังนี้:

#[derive(Default)]
struct cParams {
    iInsertMax: Option<u64>,
    iUpdateMax: Option<u64>,
    iDeleteMax: Option<u64>,
    iInstanceMax: Option<u64>,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

let p = cParams { iInsertMax: Some(10), ..Default::default() };

2
ขอบคุณฉันอ่านเร็ว แต่จะอ่านซ้ำเพื่อให้เข้าใจดีขึ้น ค่าเริ่มต้น "ตามธรรมชาติ" ที่บางภาษาใช้เช่น I believe zero, false, "" ฯลฯ จะเหมาะกับฉัน ฉันเข้าใจว่ามีนัยยะที่กว้างกว่า "ปัญหา" เล็ก ๆ ที่ต้องแก้ ความสามารถในการระบุเช่น "iVal: i64 = 0" จะตอบสนองความต้องการที่กว้างขึ้นของฉัน แต่ฉันเดาว่าจะไม่เกิดขึ้น "# [deriving (Default)]" น่าจะตอบโจทย์ความต้องการส่วนใหญ่ของฉันได้ ฉันไม่แน่ใจว่าทำไมฉันถึงใช้ -1 ในโปรแกรมทดสอบของฉัน แต่ก็ไม่จำเป็น (ตามประวัติศาสตร์) จะมีประโยชน์มาก (IMHO) ที่จะสามารถกำหนดค่าในแหล่งกำเนิดที่มีการกำหนดฟิลด์
Brian Oh

9
@BrianOh แทนกันstruct Foo { val: i64 = 0 }ได้มีการเสนอ"ค่าเริ่มต้นสำหรับฟิลด์โครงสร้าง" (เช่นบางอย่าง) และอาจปรากฏในเวอร์ชันที่ใหม่กว่า
huon

จะเป็นการดีหากมีการนำ IMO - "struct foo {.... " ฉันทำการเปลี่ยนแปลงตามที่คุณแนะนำโดยใช้โครงสร้างตามที่เขียนไว้ในคำถามของฉันและด้วยค่าเริ่มต้น แน่นอนว่าเหมาะกับฉันมากกว่าและกระชับกว่ามาก เนื่องจากไม่คุ้นเคยกับไวยากรณ์ปัญหาเล็กน้อยอย่างหนึ่งที่ฉันมีคือไม่ทราบไวยากรณ์สำหรับค่าเริ่มต้นทั้งหมด IE: ฉันใช้ "= cParams {iInsertMax: 10, ..Default :: default ()};" แต่จริงๆแล้วฉันต้องการให้ "iInstanceMax" เป็นค่าเริ่มต้นด้วย IMO ควรให้ "# [deriving (Default)]" เป็นส่วนหนึ่งของโครงสร้าง แต่ฉันคิดว่าทางเลือกอื่นเหมาะสมกับคอมไพเลอร์ดีกว่า
Brian Oh

2
ขอบคุณมากสำหรับสิ่งนั้น IMHO ค่าเริ่มต้นควรเป็นค่าเริ่มต้น IE. ฉันไม่คิดว่ามันควรจะต้องระบุค่าเริ่มต้น: ค่าเริ่มต้น ฯลฯ ฯลฯ ฉันยังคิดว่าฟิลด์ควรจะสามารถกำหนดค่าตามที่กำหนดได้ นั่นเป็นเพียงมุมมองง่ายๆของฉันและฉันตระหนักดีว่า Rust ถูกออกแบบมาให้ปลอดภัยและมีมุมมองที่กว้างกว่าของฉันมาก เมื่อมีคนเรียนรู้ภาษา (หรืออย่างน้อยก็ฉัน) การใช้งานในปัจจุบันดูเหมือนจะยุ่งยากเล็กน้อย Rust ไม่ใช่ภาษา IMHO ที่เรียบง่ายและยิ่งสามารถทำได้มากขึ้นเพื่อให้ง่ายขึ้นอย่างน้อยก็ยิ่งดีสำหรับฉัน
Brian Oh

4
จำเป็นต้องกำหนดค่าดีฟอลต์สำหรับฟิลด์ทั้งหมดเมื่อนำไปใช้งานDefaultกับ struct หรือไม่?
Matthew Stevenson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.