Rust 语言从入门到实战
唐刚
Rust 语言中文社区联合创始人
5266 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 36 讲
Rust 语言从入门到实战
15
15
1.0x
00:00/00:00
登录|注册

05|复合类型(上):结构体与面向对象特性

你好,我是 Mike。今天我们来学习 Rust 中的复合类型——结构体。
结构体是由其他的基础类型或复合类型组成的,当它所有字段同时实例化后,就生成了这个结构体的实例。在 Rust 中,结构体使用 struct 关键字进行定义。
这节课我们会通过各种各样的示例来了解结构体,其中有部分示例来自于官方 The Book。我们一起来看一下。

结构体示例

下面我们先来看一下结构体示例,定义一个 User 结构体。
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
示例中的 User 结构体由 4 个字段组成。
active 字段:bool 类型,表示这个用户是否是激活状态。
username 字段:字符串类型,表示这个用户的名字。
email 字段:字符串类型,表示这个用户的邮箱名。
sign_in_count 字段:u64 类型,用来记录这个用户登录了多少次。
User 完全由 4 个基础类型的字段组合而成。User 的实例化需要这 4 个字段同时起作用,缺一不可。比如:
fn main() {
let user1 = User {
active: true,
username: String::from("someusername123"),
email: String::from("someone@example.com"),
sign_in_count: 1,
};
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Rust中的结构体是复合类型的重要实现方式,包括命名结构体、元组结构体和单元结构体。结构体的字段可以是引用类型或带有所有权的类型,而通过关键字impl可以为结构体实现方法,包括实例方法和关联函数。此外,文章还介绍了Rust中的构造函数约定,即使用new()或from()等命名的关联函数来实例化结构体。在对结构体做实例化时,Rust提供了一个便利的设施Default,可以通过Default::default()或类型名::default()来实例化结构体。文章还强调了Rust语言并不是一门完整的面向对象语言,但通过trait等机制能够提供更灵活的抽象和配置。总之,本文通过深入浅出的方式介绍了Rust中结构体的各种特性,为读者提供了全面的了解和学习Rust中复合类型的知识。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Rust 语言从入门到实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(24)

  • 最新
  • 精选
  • 约书亚
    思考题有点像脑筋急转弯 我们不能直接对原生类型做impl 但我们可以用newtype模式对i8封装一下,再impl

    作者回复: 棒

    2023-10-30归属地:天津
    11
  • 下雨天
    思路题:基本数据类型无法实现impl。 目前知道可以给基本数据类型添加操作的方式,通过 trait. trait Operate { fn plus(self) -> Self; } impl Operate for i8 { fn plus(self) -> Self { self + self } } fn main() { let a = 1i8; println!("{}",a.plus()); } rust有多少种方式可以给基本数据扩展方法呢,欢迎各位大佬指路?

    作者回复: 最基本的就是你这种,另外就是用newtype方法包一下。👍

    2023-10-31归属地:湖北
    2
    6
  • soddygo
    用”impl Default for i8”实践了下,不能给 i8实现impl,错误提示大意就是违反孤儿规则(Rust's orphan rules )…直觉上,基础类型如果允许impl改变特性,一些逻辑会变的很奇怪…用struct包裹起来,impl就可以正常使用了

    作者回复: 👍👍

    2023-10-31归属地:四川
    4
  • 水不要鱼
    老师,元组结构体是不是有点没啥必要,而且不太建议使用,因为对代码可读性来说会是一场灾难,比如 Color 的定义,用 struct {r g b} 这种描述就清晰很多,还有 Point 也是,定义 struct {x y z} 也比元组的方式清楚。。我感觉只要涉及 struct 建模的,肯定每个字段都会有含义和价值,给一个清楚的命名会比 s.0 s.1 s.2 这种元组的引用方式要更好。。所以感觉元组结构体似乎有些多余了哈哈,个人见解

    作者回复: 有的哈,文中已说明。有可能你目前比较喜欢 struct {x y z} 这种形式吧。

    2023-11-05归属地:广东
    3
    2
  • Geek_c75753
    文章内容组织的很好,读起来很顺畅,有时看着看着有了疑惑,带着疑惑继续读下去,发现很快就给了解释。非常感谢作者

    作者回复: 感谢🙏

    2023-11-15归属地:北京
    1
  • 一个人旅行
    思考题: 不可以,i8是rust的内置的类型。 如果要在其他模块中实现方法,可以使用实现trait的方式来实现方法。 但是需要注意,trait和类型至少有一个要在当前的模块中。

    作者回复: 👍

    2023-10-30归属地:北京
    1
  • 周鹏
    #[derive(Debug)] 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, }; // 在这里,取了实例的引用 let r1 = &rect1; let r2 = &&rect1; let r3 = &&&&&&&&&&&&&&&&&&&&&&rect1; // 不管有多少层 let r4 = &&r1; // 以下4行都能打印出正确的结果 r1.area(); r2.area(); r3.area(); r4.area(); } 并没有打印出来的相关代码,要在area方法里面添加,或者修改注释。

    作者回复: 确实, 注释有bug,谢谢指正

    2024-03-13归属地:福建
  • 脱尼
    这节课中的很多知识点,可以从 JS,TS, JAVA,Object-c 中找到语法的影子。例如:结构体字段的赋值简写是来自 JS或者 TS, impl + self 的实现妥妥 OC 的既视感,还有 derive, trait 在 JAVA 中注解的表达和实现。总之,感觉很奇妙。感谢老师!RUST博采众长了!

    作者回复: 👍👍👍

    2024-02-18归属地:广东
  • Geek_e5eb33
    老师请教个问题,rust 有没有类似于 golang 的 interface{} 或者 java 的 Object,我现在遇到的问题是,tcp 另一端给的数据,比如 {"name": "x", "value": 1},{"name": "x", "value": "xxx"}, {"name": "x", "value": [1,2,3,4]},这样的数据,在 rust 结构体中怎么表示多类型,且能被 serde 库序列化/反序列化呢

    作者回复: 这种schema变化的数据,不太方便映射到Rust结构体上,但是也可以有一些变化。比如 Option 字段,serde 有这方面的标识,比如 https://serde.rs/field-attrs.html#skip。另外,可以用 serde_json 直接处理这种 schemaless 的数据。

    2023-12-19归属地:安徽
  • superggn
    不行, 因为孤儿原则?

    作者回复: 不是孤儿原则。在Rust中,你不能直接对基本类型(如i8)进行实现(impl)。这是因为Rust的设计者们决定不允许对基本类型进行实现,以防止在全局范围内改变基本类型的行为。这样可以确保基本类型在所有情况下的行为都是一致的,避免了可能的混乱和错误。

    2023-12-13归属地:北京
    2
收起评论
显示
设置
留言
24
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部