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

server/2024/9/25 8:26:07/

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

大家好,

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

简介

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

例如:

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

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

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

语法的基本示例:

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

初始化和访问 结构体

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

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

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

示例:

rust">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 声明为我们类的实现中的一个 方法,我们可以这样做:

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

调用该方法:

rust">order1.display_order_info();

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

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

代码:

rust">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

我们可以这样做:

rust">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 中,元组结构体是轻量级的结构体,它使用元组来定义字段,提供了一种创建新类型的方式,而不需要逐个命名每个字段。

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

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

打印实例

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

示例:

rust">
#[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);  
}

输出:

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

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

rust">#[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);  
}

输出:

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

关联函数

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

示例:

rust">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 程序中创建清晰和结构化的数据表示提供了强大的工具。无论是表示电子商务系统中的订单还是定义二维空间中的坐标,结构体都使开发人员能够高效地封装和操作数据。


http://www.ppmy.cn/server/17826.html

相关文章

Stable Diffusion Web UI Windows部署及坑

文章目录 1、准备2、Miniconda安装3、git安装4、安装CUDA4、开始部署遇到的坑 1、准备 官网需要翻墙软件最少6G内存,显卡在2060以上 2、Miniconda安装 这是一个运行python的环境管理工具进入官网点击download下载打开文件一路到 Advanced Options,勾选…

06.JAVAEE之线程4

1.定时器 1.1 定时器是什么 定时器也是软件开发中的一个重要组件. 类似于一个 " 闹钟 ". 达到一个设定的时间之后 , 就执行某个指定好的代码. 约定一个时间,时间到达之后,执行某个代码逻辑, 定时器非常常见,尤其是在进行网络通信的时候, 需要有等待的最大时间&…

【优秀AI项目】每日跟踪 OpenVoice ,AI快站,OpenVoice

持续更新好玩的开源AI项目或AI商业应用体验 一起来玩转AI!! 1 huggingface 国内镜像站:AI 快站 HUggingface被墙了,emmmmm 所以我之前玩模型的一大感觉就是 下载什么模型之类的太难受了!服了 看到一个镜像站——…

【MySQL】创建和管理数据库

1、创建数据库 创建数据库——CREATE DATABASE 数据库名;创建数据库并指定字符集——CREATE DATABASE 数据库名 CHARACTER SET 字符集;判断数据库是否已经存在,不存在则创建数据库——CREATE DATABASE IF NOT EXISTS 数据库名; 2、使用数据库 查看当前所有的数据库…

Kubernetes(k8s)的概念以及使用

k8s的概念: K8s是指Kubernetes,是一个开源的容器编排和管理平台。它最初由Google开发,并于2014年将其开源。Kubernetes旨在简化容器化应用程序的部署、扩展和管理。 Kubernetes提供了一种可靠且可扩展的平台,用于管理容器化应用…

华媒舍:百度竞价排名如何提升点击率

在网络推广中,提升点击率是十分重要的。运用百度搜索引擎广告是一种常用的提升点击率的形式。而百度竞价推广是搜索引擎所提供的一种付费流量方法,根据提高网站在搜索结果中的排名,可以有效提升点击率。下面我们就详细介绍如何运用百度竞价推…

什么是用户体验(UX)文案,为什么它很重要?

网上购物如今比以往任何时候都更加相关。所以我们将以此为例说明什么是用户体验(UX)文案,以及为什么它很重要。 假设你去了一个在线商店。你需要执行一系列操作: 找到合适的部分选择你感兴趣的产品弄清楚它们是什么,…

图片恢复光影效果;通过拖拽等操作编辑3D实物;Cohere开源RAG技术;智能对话客服工具ChatGPT-On-CS

✨ 1: IntrinsicAnything 可以在光照条件未知的情况下,从单一图像中恢复出物体的材质 它就像是一位拥有高超技艺的画家,能够在仅有一张照片的情况下,准确地揭示出画中物体的材质,甚至在没有知道光线条件的情况下,都能…