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

07|类型与类型参数:给Rust小助手提供更多信息

你好,我是 Mike。今天我们一起来学习 Rust 中类型相关的知识。
这块儿知识在其他大部分语言入门材料中讲得不多,但是对于 Rust 而言,却是非常重要而有趣的。我们都知道,计算机硬件执行的代码其实是二进制序列。而对一个二进制值来说,正是类型赋予了它意义
比如 01100001 这个二进制数字,同样的内存表示,如果是整数,就表示 97。如果是字符,就表示 'a' 这个 char。如果没有类型去赋予它额外的信息,当你看到这串二进制编码时,是不知道它代表什么的。

类型

《Programming.with.Types》2019 这本书里对类型做了一个定义,翻译出来是这样的:类型是对数据的分类,这个分类定义了这些数据的意义、被允许的值的集合,还有能在这些数据上执行哪些操作。编译器或运行时会检查类型化过程,以确保数据的完整性,对数据施加访问限制,以及把数据按程序员的意图进行解释。
有些情况下,我们会简化讨论,把操作部分忽略掉,所以我们可以简单地把类型看作集合,这个集合表达了这个类型的实例能取到的所有可能的值

类型系统

这本书里还定义了类型系统的概念。
书里是这样说的:类型系统是一套规则集——把类型赋予和施加到编程语言的元素上。这些元素可以是变量、函数和其他高阶结构。类型系统通过你在代码中提供的标注来给元素赋予类型,或者根据它的上下文隐式地推导某个元素的类型。类型系统允许在类型间做各种转换,同时禁止其他的一些转换。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Rust类型系统是本文的核心主题,涵盖了类型参数的重要性和灵活性,以及在函数和方法中的应用。文章首先介绍了类型参数的作用,通过示例展示了如何使用类型参数来避免重复代码,提高代码的清晰度和可维护性。接着,文章详细讲解了在函数和方法中使用类型参数的方法,以及如何对类型参数进行约束。随后,文章介绍了Rust类型体系的构建方法,包括结构体、枚举、洋葱结构和newtype模式。通过示例代码和解释,读者可以深入了解Rust类型系统的构建和应用。整体而言,本文深入浅出地介绍了Rust类型系统的基本概念和高级应用,适合想要深入了解Rust类型系统的读者阅读。文章还讲解了4种类型体系建模方法,为读者提供了更多实践过程中的理解。

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

全部留言(6)

  • 最新
  • 精选
  • 小云同学
    思考题:"为泛型实现了一个方法,能否再为具化类型实现一个同名方法",取决于这个泛型能否表示相应的具化类型。比如为泛型 T 和 String 实现了相同的方法,由于 T 没有施加任何约束,它可以代表 String。那么当调用方法时,对于具化类型 String 来说,要调用哪一个呢?因此会出现歧义,编译器会报错:方法被重复定义了。 但如果给泛型 T 施加了一个 Copy 约束,要求 T 必须实现了 Copy trait,那么就不会报错了,因为此时 T 代表不了 String,所以调用方法不会出现歧义。但如果再为 i32 实现一个同名方法就会报错了,因为 i32 实现了 Copy,它可以被 T 表示。 PS:老师我在 06 讲提了一个问题,之前在学 Rust 的时候就一直困扰着我,还麻烦老师解答一下。

    作者回复: 👍

    2023-11-03归属地:中国台湾
    8
  • 一个人旅行
    不能,编译器会提示duplicate definitions for XXXXX。 如果想为具化类型再实现同样的方法,则可以定义一个trait,用具化类型实现这个trait,来达到"为具化类型再实现同样的方法“的目的。

    作者回复: 👍

    2023-11-03归属地:北京
    3
  • Geek_de05b4
    impl<T: std::ops::Add<Output = T>> Bar<T> { fn plus(self, other: Bar<T>) -> T { self.value + other.value } } impl Bar<u32> { fn plus(&self, other: &Bar<u32>) -> u32 { self.value + other.value } } //Output: error[E0592]: duplicate definitions with name `plus` --> src/main.rs:64:5 | 64 | fn plus(self, other: Bar<T>) -> T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `plus` ... 70 | fn plus(&self, other: &Bar<u32>) -> u32 { | --------------------------------------- other definition for `plus` 不能

    作者回复: 👍

    2023-11-03归属地:上海
    2
  • -Hedon🍭
    思考题:核心点就在于不能为同一个类型实现 2 个相同函数签名的方法,因为这会引起方法冲突。 编译报错如下: error[E0592]: duplicate definitions with name `print` --> examples/generic.rs:7:5 | 7 | fn print(&self) { | ^^^^^^^^^^^^^^^ duplicate definitions for `print` ... 13 | fn print(&self) { | --------------- other definition for `print` 所以一般情况下,如果 impl<T> 后面的 T 没有任何的约束,那么就表示为所有类型的 T 都实现了方法,比如说 print(),这个时候是不能为具化类型再次实现 print() 的,因为这个时候就产生了方法冲突。 但是,如果 impl<T: std::fmt:Display> 后面的 T 是有约束的,那么其实只为符合这个约束的类型实现了 print(),其余类型是没有实现的,所以是可以为其余具化类型实现相同的方法的。 如: ```rust struct Point<T> { x: T, y: T, } struct NotDisplay { a: u32, } impl<T: std::fmt::Display> Point<T> { fn print(&self) { println!("Point: {}, {}", self.x, self.y); } } impl Point<NotDisplay> { fn print(&self) { println!("not display"); } } ```

    作者回复: 很棒

    2023-11-08归属地:湖北
    1
  • Noya
    思考题:通常是不能, 但是可以通过 trait 进行特化

    作者回复: 对的

    2023-11-09归属地:浙江
  • 伯阳
    和Java的范型类似
    2023-11-03归属地:北京
    1
收起评论
显示
设置
留言
6
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部