前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >rust 中的结构体

rust 中的结构体

作者头像
用户3147702
发布2022-06-27 17:09:28
6840
发布2022-06-27 17:09:28
举报
文章被收录于专栏:小脑斧科技博客

1. 引言

此前的文章中,我们已经较为详细的介绍了 Rust 的基本语法:

在许多语言中,我们都早就接触过结构体这种复合数据类型,在面向对象的语言中,类的概念与之非常类似,在 rust 语言中,结构体同样是一种实用且强大的数据类型,那么,在 rust 语言中,结构体这种数据类型要如何定义和使用呢?

2. 结构体的定义

在 rust 中,元组、数组、结构体都是数据的复合结构,他们的不同之处在于:

  1. 数组:每个元素必须拥有相同的数据类型;
  2. 元组:每个元素拥有各自的类型;
  3. 结构体:每个元素拥有各自的类型,且每个元素都需要被命名。

下面是一个典型的结构体的定义:

代码语言:javascript
复制
struct User {
    username: String,
    email: String,
    active: bool
}

看起来除了字段命名和类型依据着 rust 独特的语言格式外,其他的方面和其他语言的结构体定义并没有很大的不同。

rust 也允许声明不为任何字段命名的结构体,这样的结构体被称为“元组结构体”,相当于有命名的元组:

代码语言:javascript
复制
struct Color(i32, i32, i32);
  • 需要注意的是,此处定义使用了 String 类型,而不是 &str 类型,由于 rust 独特的生命周期问题,会造成使用 &str 类型会产生一些麻烦,后续章节将会进一步介绍。

3. 结构体的使用

3.1 示例

代码语言:javascript
复制
let user1 = User {
    email: String::from("amy@gmail.com"),
    username: String:from("Amy"),
    active: true
};

println!("{}'s email is {}", user1.username, user1.email);

这是一个典型的结构体的使用。

3.2 可变性

如果我们想要修改结构体变量的某个字段,那就必须将结构体变量声明为可变的 mut

代码语言:javascript
复制
let mut user1 = User {
    email: String::from("amy@gmail.com"),
    username: String:from("Amy"),
    active: false
};


user1.active = true;
  • 需要注意的是,rust 不支持单独声明某些字段可变,一旦实例被声明为可变,那么就意味着整个结构体中的任何一个字段均是可变的。

3.3 用语法糖简化结构体使用

1. 变量名与字段名同名时的简化

代码语言:javascript
复制
fn build_user(email: String, username: String) -> User {
    User {
        email,
        username,
        active: true
    }
}

2. 来自其他实例的字段

代码语言:javascript
复制
let user2 = User {
    email: String::from("tom@gmail.com"),
    username: String::from("Tom"),
    ..user1
}

这里语法 ..user1 表示其余字段均来自于 user1 实例。

4. 方法

在面向对象的语言中,对象除了拥有自己的属性外,往往还要拥有许许多多的行为,这些行为一般被定义为类的 method,也就是方法。

即使是在 C 语言这样的非面向对象的语言中,也可以通过函数指针的方式为结构体添加行为,在 rust 中,同样支持为结构体添加方法。

4.1 定义方法

代码语言:javascript
复制
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()
    );
}

在上述代码中,struct 关键字定义了一个结构体 Rectangle,然后通过 impl 将若干方法与结构体绑定,通过实例的 . 操作符,我们就可以实现方法的调用。

在 impl 块中,我们可以使用 Self 作为原类型的别名。

而针对一个结构体,impl 块并非只能有一个,一个结构体可以拥有很多 impl 块,你甚至可以为每一个方法或是关联函数创建一个单独的 impl 块。

4.2 关联函数

而在impl中定义的不需要传递 &self 参数的函数被称为”关联函数“,非常类似于 java 语言中的 static 方法,例如:

代码语言:javascript
复制
impl Rectangle {
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

fn main() {
   let rectangle = Rectangle::square(4);
}

如上示例中所写的,结构体的关联函数需要通过结构体类型名与 :: 符号来进行调用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小脑斧科技博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 引言
  • 2. 结构体的定义
  • 3. 结构体的使用
    • 3.1 示例
      • 3.2 可变性
        • 3.3 用语法糖简化结构体使用
          • 1. 变量名与字段名同名时的简化
          • 2. 来自其他实例的字段
      • 4. 方法
        • 4.1 定义方法
          • 4.2 关联函数
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档