学习 Rust 的第九天:如何使用结构体

发布于:2024-04-26 ⋅ 阅读:(32) ⋅ 点赞:(0)

好的,我已经收到完整的内容了。我会按照规则对其进行翻译,稍等片刻。

大家好,

今天是学习 Rust 的第九天,我们要讨论一个非常重要的概念,即 结构体(structs),它可以将相关的数据组合在一起,使我们的代码更具可读性。

简介

在 Rust 中,结构体 是用于定义自定义类型的基本数据结构,它将多个字段与不同的数据类型捆绑在一起,并封装相关数据。它为在 Rust 程序中以简洁和结构化的方式组织和操作数据提供了强大的工具。

例如:

当你在任何电子商务平台上下订单时,你的订单包含诸如以下信息:

{  
   "收货地址" : "XYZ 街道,_______",  
   "产品编号" : 129,  
   "最后位置":"纽约市",  
   "数量":3,  
   "用户编号" : "xyz-abc-user"  
   ...  
   等等  
}

因此,为了将所有这些数据存储在内存中的一个地方,我们可以使用结构体。

语法的基本示例:

struct Order{  
  delivery_address: String,  
  quantity: u32,  
  product_id: u32,  
  email_address: String,  
}

初始化和访问 结构体

要将数据存储在上述 结构体 中并将其存储在变量中,可能看起来像这样:

let order1 = Order{  
    delivery_address: String::from("测试地址"),  
    quantity: 6,  
    product_id: 96240,  
    email_address: String::from("shafinmurani9@gmail.com"),  
};

要访问 结构体,我们可以使用 . 运算符。

示例:

struct Order{  
  delivery_address: String,  
  quantity: u32,  
  product_id: u32,  
  email_address: String,  
}  
fn main(){  
  let order1 = Order{  
    delivery_address: String::from("测试地址"),  
    quantity: 6,  
    product_id: 96240,  
    email_address: String::from("shafinmurani9@gmail.com"),  
  };  
  display_order_info(&order1);  
}  
  
fn display_order_info(order: &Order){  
    print_banner();  
    println!("收货地址: {}",order.delivery_address);  
    println!("数量: {}",order.quantity);  
    println!("产品编号: {}",order.product_id);  
    println!("邮箱地址: {}",order.email_address);  
}  
fn print_banner(){  
    for _i in 0..=25{  
        print!("*");  
    }  
    println!("");  
    println!("订单信息: ");  
    for _j in 0..=25{  
        print!("*");  
    }  
    println!("");  
}

输出:


**************************  
订单信息:  
**************************  
收货地址: 测试地址  
数量: 6  
产品编号: 96240  
邮箱地址: shafinmurani9@gmail.com
  • 该代码定义了一个名为 Order结构体,其中有四个字段:delivery_addressquantityproduct_idemail_address
  • main 函数内,创建了一个名为 order1Order 实例,并为其字段分配了特定的值。
  • display_order_info 函数以 Order 结构体的引用作为参数,并打印出其信息。
  • 在打印订单信息之前,调用了 print_banner 函数以显示一个横幅,指示订单详细信息的开始。
  • print_banner 函数打印了一个由星号组成的横幅,以视觉上分隔订单信息,以提高可读性。
  • 在打印横幅后,display_order_info 函数打印了 Order 结构体的每个字段及其相应的值。

正如我们所看到的,display_order_info 函数与 order 结构相关联,并且可以增强代码的可读性。

实现

实现类似于类中的方法,与 结构体 密切相关的函数可以声明为 结构体 的实现。

要将 display_order_info 声明为我们类的实现中的一个 方法,我们可以这样做:

impl Order{  
  fn display_order_info(&self){  
    print_banner();  
    println!("收货地址: {}",self.delivery_address);  
    println!("数量: {}",self.quantity);  
    println!("产品编号: {}",self.product_id);  
    println!("邮箱地址: {}",self.email_address);  
  }  
}

调用该方法:

order1.display_order_info();

请注意,在函数参数中我指定了 &self。这是对结构体实例本身的引用,允许方法访问和操作结构体的数据而无需拥有它。

重要概念:方法是在实现块内部的带有 self 参数的函数。

代码:

struct Order{  
  delivery_address: String,  
  quantity: u32,  
  product_id: u32,  
  email_address: String,  
}  
impl Order{  
  fn display_order_info(&self){  
    print_banner();  
    println!("收货地址: {}",self.delivery_address);  
    println!("数量: {}",self.quantity);  
    println!("产品编号: {}",self.product_id);  
    println!("邮箱地址: {}",self.email_address);  
  }  
}  
fn main(){  
  let order1 = Order{  
    delivery_address: String::from("测试地址"),  
    quantity: 6,  
    product_id: 96240,  
    email_address: String::from("shafinmurani9@gmail.com"),  
  };  
  order1.display_order_info();  
}  
  
fn print_banner(){  
    for _i in 0..=25{  
        print!("*");  
    }  
    println!("");  
    println!("订单信息: ");  
    for _j in 0..=25{  
        print!("*");  
    }  
    println!("");  
  
}

输出结果保持不变。

从另一个实例复制值

假设我们想要创建另一个 Order 实例,并从 order1 复制 quantityproduct_id

我们可以这样做:

let order1 = Order{  
    delivery_address: String::from("测试地址"),  
    quantity: 6,  
    product_id: 96240,  
    email_address: String::from("shafinmurani9@gmail.com"),  
  };  
let order2 = Order{  
    email_address: String::from("test@test.com"),  
    delivery_address: String::from("address2"),  
    ..order1  
  };

调用 display_product_info 将输出:


**************************  
订单信息:  
**************************  
收货地址: 测试地址  
数量: 6  
产品编号: 96240  
邮箱地址: shafinmurani9@gmail.com  
  
**************************  
订单信息:  
**************************  
收货地址: address2  
数量: 6  
产品编号: 96240  
邮箱地址: test@test.com

好的,我会开始翻译下面的内容。

元组结构体

在 Rust 中,元组结构体是轻量级的结构体,它使用元组来定义字段,提供了一种创建新类型的方式,而不需要逐个命名每个字段。

struct 2d_point(i32, i32);  
  
fn main() {  
    let origin = 2d_point(0, 0);  
    println!("坐标:({}, {})", origin.0, origin.1);  
}

在这里,我们本可以直接使用元组,但这样做的话,我们无法在特定函数中传递具有任意值的元组,这样可以防止这种情况发生。

打印实例

在调试时,可能会有需要打印实例的情况,而不是逐个输出值,此时,你可以使用 #[derive(Debug)] 特性。

示例:


#[derive(Debug)]  
struct Order{  
  delivery_address: String,  
  quantity: u32,  
  product_id: u32,  
  email_address: String,  
}  
  
fn main(){  
let order1 = Order{  
    delivery_address: String::from("测试地址"),  
    quantity: 6,  
    product_id: 96240,  
    email_address: String::from("shafinmurani9@gmail.com"),  
  };  
  println!("订单 1:{:?}",order1);  
}

输出:

Order { delivery_address: "测试地址", quantity: 6, product_id: 96240, email_address: "shafinmurani9@gmail.com" }

我们可以使用 println!("订单 1:{:#?}",order1); 进行 pretty print

#[derive(Debug)]  
struct Order{  
  delivery_address: String,  
  quantity: u32,  
  product_id: u32,  
  email_address: String,  
}  
  
fn main(){  
let order1 = Order{  
    delivery_address: String::from("测试地址"),  
    quantity: 6,  
    product_id: 96240,  
    email_address: String::from("shafinmurani9@gmail.com"),  
  };  
  println!("订单 1:{:#?}",order1);  
}

输出:

订单 1Order {  
    delivery_address: "测试地址",  
    quantity: 6,  
    product_id: 96240,  
    email_address: "shafinmurani9@gmail.com",  
}

关联函数

关联函数类似于方法,但是它没有传递给它的 self 参数,而是采用其他形式的值。

示例:

struct Order{  
  delivery_address: String,  
  quantity: u32,  
  product_id: u32,  
  email_address: String,  
}  
impl Order{  
  fn display_order_info(&self){  
    print_banner();  
    println!("收货地址: {}",self.delivery_address);  
    println!("数量: {}",self.quantity);  
    println!("产品编号: {}",self.product_id);  
    println!("邮箱地址: {}",self.email_address);  
  }  
  
  fn generate_order(delivery_address: &str, quantity: u32, product_id: u32, email_address: &str) -> Order{  
    Order{  
      delivery_address: String::from(delivery_address),  
      quantity,  
      product_id,  
      email_address: String::from(email_address),  
    }  
  }  
}  
fn main(){  
  let order1 = Order::generate_order("测试地址", 2, 93521, "shafinmurani9@gmail.com");  
  order1.display_order_info();  
}  
  
fn print_banner(){  
    for _i in 0..=25{  
        print!("*");  
    }  
    println!("");  
    println!("订单信息: ");  
    for _j in 0..=25{  
        print!("*");  
    }  
    println!("");  
  
}

输出:


**************************  
订单信息:  
**************************  
收货地址: 测试地址  
数量: 2  
产品编号: 93521  
邮箱地址: shafinmurani9@gmail.com

注意我如何使用 Order::generate_order(...) 调用关联函数,而不是 variable_name.function_name()

后一种语法用于在实例上调用方法。

结论

结构体是 Rust 编程的基础,允许开发人员将相关数据组织成自定义类型。通过将多个字段与不同的数据类型捆绑在一起,结构体为在 Rust 程序中创建清晰和结构化的数据表示提供了强大的工具。无论是表示电子商务系统中的订单还是定义二维空间中的坐标,结构体都使开发人员能够高效地封装和操作数据。