深入掌握 Rust 结构体:从模板到实例化的完整指南

深入掌握Rust结构体:从模板到实例化的完整指南Rust是一门以安全性和并发性著称的编程语言,其核心之一便是结构体(struct)的灵活性。结构体能够帮助我们定义复杂的数据类型,并且可以通过特定的语法进行高效的数据更新和复用。在Rustlings实践练习中,我们将深入探讨结构体的定义、实

深入掌握 Rust 结构体:从模板到实例化的完整指南

Rust 是一门以安全性和并发性著称的编程语言,其核心之一便是结构体(struct)的灵活性。结构体能够帮助我们定义复杂的数据类型,并且可以通过特定的语法进行高效的数据更新和复用。在 Rustlings 实践练习中,我们将深入探讨结构体的定义、实例化以及使用模板更新语法(update syntax)创建新实例的技巧。

本文通过一个实际的 Rustlings 练习示例,演示了如何使用结构体来创建复杂数据类型,并使用 Rust 的结构体更新语法有效地复用现有结构体的数据模板。文章还详细讲解了代码的每个部分,包括如何定义结构体、创建模板、实例化结构体,并根据需要修改其中的部分字段,达到高效复用的目的。通过这些技巧,开发者可以编写更简洁、高效的代码。

rustlings 实操

// structs2.rs
//
// Address all the TODOs to make the tests pass!
//
// Execute `rustlings hint structs2` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

#[derive(Debug)]
struct Order {
    name: String,
    year: u32,
    made_by_phone: bool,
    made_by_mobile: bool,
    made_by_email: bool,
    item_number: u32,
    count: u32,
}

fn create_order_template() -> Order {
    Order {
        name: String::from("Bob"),
        year: 2019,
        made_by_phone: false,
        made_by_mobile: false,
        made_by_email: true,
        item_number: 123,
        count: 0,
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn your_order() {
        let order_template = create_order_template();
        // TODO: Create your own order using the update syntax and template above!
        let your_order = Order {
            name: String::from("Hacker in Rust"),
            count: 1,
            ..order_template
        };
        assert_eq!(your_order.name, "Hacker in Rust");
        assert_eq!(your_order.year, order_template.year);
        assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
        assert_eq!(your_order.made_by_mobile, order_template.made_by_mobile);
        assert_eq!(your_order.made_by_email, order_template.made_by_email);
        assert_eq!(your_order.item_number, order_template.item_number);
        assert_eq!(your_order.count, 1);
    }
}

代码解释及优化:

这段代码的核心是通过 Rust 的 结构体更新语法.. 语法)来实现新结构体的快速实例化,并保留部分字段的值。具体包括以下几个部分:

1. 结构体定义:

首先定义了一个名为 Order 的结构体,包含多个字段:

#[derive(Debug)]
struct Order {
    name: String,
    year: u32,
    made_by_phone: bool,
    made_by_mobile: bool,
    made_by_email: bool,
    item_number: u32,
    count: u32,
}
  • name: 用来存储订单的用户名。
  • year: 订单创建年份。
  • made_by_phone, made_by_mobile, made_by_email: 这些布尔值用来表示订单是否通过不同的渠道创建。
  • item_number: 表示商品的编号。
  • count: 商品数量。

2. 创建结构体模板:

create_order_template 函数创建了一个订单模板:

fn create_order_template() -> Order {
    Order {
        name: String::from("Bob"),
        year: 2019,
        made_by_phone: false,
        made_by_mobile: false,
        made_by_email: true,
        item_number: 123,
        count: 0,
    }
}

这个模板代表了一个固定的订单,假设它由电子邮件创建,商品编号为 123,商品数量为 0。通过该模板,可以快速创建类似的订单。

3. 更新语法:

通过 your_order 函数,我们使用模板数据,创建了一个新的订单,并且只修改了 namecount 字段:

let your_order = Order {
    name: String::from("Hacker in Rust"),
    count: 1,
    ..order_template
};
  • name: String::from("Hacker in Rust")count: 1 覆盖了模板中的 namecount 字段。
  • ..order_template 使用模板 order_template 中的其他字段值。

这样,我们就可以在保持大部分字段不变的情况下,只修改必要的字段。这种语法不仅简洁,而且非常高效,尤其在需要复用模板时非常实用。

4. 测试代码:

为了确保代码的正确性,使用了 #[test] 来测试 your_order,验证新订单是否正确更新了字段,并保持了模板中的其他值。

assert_eq!(your_order.name, "Hacker in Rust");
assert_eq!(your_order.year, order_template.year);
assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
assert_eq!(your_order.made_by_mobile, order_template.made_by_mobile);
assert_eq!(your_order.made_by_email, order_template.made_by_email);
assert_eq!(your_order.item_number, order_template.item_number);
assert_eq!(your_order.count, 1);

这些测试确保了 your_ordernamecount 字段被正确更新的同时,其他字段与模板保持一致。


完善后的代码:

#[derive(Debug)]
struct Order {
    name: String,
    year: u32,
    made_by_phone: bool,
    made_by_mobile: bool,
    made_by_email: bool,
    item_number: u32,
    count: u32,
}

fn create_order_template() -> Order {
    Order {
        name: String::from("Bob"),
        year: 2019,
        made_by_phone: false,
        made_by_mobile: false,
        made_by_email: true,
        item_number: 123,
        count: 0,
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn your_order() {
        let order_template = create_order_template();
        let your_order = Order {
            name: String::from("Hacker in Rust"),
            count: 1,
            ..order_template
        };
        assert_eq!(your_order.name, "Hacker in Rust");
        assert_eq!(your_order.year, order_template.year);
        assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
        assert_eq!(your_order.made_by_mobile, order_template.made_by_mobile);
        assert_eq!(your_order.made_by_email, order_template.made_by_email);
        assert_eq!(your_order.item_number, order_template.item_number);
        assert_eq!(your_order.count, 1);
    }
}

总结

在本次练习中,我们深入理解了 Rust 中结构体的使用,尤其是通过 结构体更新语法 快速生成新实例的优势。这种语法极大简化了代码书写,避免重复定义相同的字段,同时保持了代码的清晰性和可读性。通过 Rustlings 的练习,开发者可以更好地掌握 Rust 语言的特性,并将这些技巧应用到实际项目中,以提高开发效率。

参考

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
寻月隐君
寻月隐君
0x750E...B6f5
不要放弃,如果你喜欢这件事,就不要放弃。如果你不喜欢,那这也不好,因为一个人不应该做自己不喜欢的事。