惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News - Newest:
Hacker News - Newest: "LLM"
Webroot Blog
Webroot Blog
S
Security @ Cisco Blogs
H
Heimdal Security Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
www.infosecurity-magazine.com
www.infosecurity-magazine.com
N
News and Events Feed by Topic
H
Hacker News: Front Page
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
SecWiki News
SecWiki News
N
News | PayPal Newsroom
T
Tor Project blog
W
WeLiveSecurity
A
Arctic Wolf
Security Archives - TechRepublic
Security Archives - TechRepublic
S
Secure Thoughts
月光博客
月光博客
AWS News Blog
AWS News Blog
D
Docker
C
CERT Recently Published Vulnerability Notes
MyScale Blog
MyScale Blog
Google Online Security Blog
Google Online Security Blog
大猫的无限游戏
大猫的无限游戏
T
The Blog of Author Tim Ferriss
I
InfoQ
人人都是产品经理
人人都是产品经理
Recent Announcements
Recent Announcements
Google DeepMind News
Google DeepMind News
Hacker News: Ask HN
Hacker News: Ask HN
Blog — PlanetScale
Blog — PlanetScale
博客园 - 【当耐特】
Engineering at Meta
Engineering at Meta
Stack Overflow Blog
Stack Overflow Blog
Recorded Future
Recorded Future
罗磊的独立博客
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
The Exploit Database - CXSecurity.com
D
DataBreaches.Net
S
Security Affairs
WordPress大学
WordPress大学
T
Threatpost
Microsoft Security Blog
Microsoft Security Blog
V
Vulnerabilities – Threatpost
The Hacker News
The Hacker News
S
SegmentFault 最新的问题
B
Blog RSS Feed
Project Zero
Project Zero
P
Proofpoint News Feed

文章列表 on polarisxu

通过一个例子让你彻底掌握 Go 工作区模式 这道题正确率竟然只有 22% Go 开源项目推荐:一个简单的 Go 练手项目 go test 如何禁用缓存? Go1.18 快讯:constraints 包被移除标准库 跟着 Go 作者学泛型 「2022 版」轻松搞定 Go 开发环境 鹅厂小哥用行动反对加班:程序员加班能被终结吗? Go 为什么选择 Gopher 作为吉祥物? 本地如何配置多个 GitHub/Gitee 账号? 为 Java 开发者准备的 Go 教程 02:Java 有而 Go 无 GitHub 发现了 studygolang 项目依赖的漏洞 Typora 宣布收费后,这款开源 Markdown 编辑器火了 为 Java 开发者准备的 Go 教程 01:漫游了 我的 2021 年终总结 泛型版 singleflight:Go 中如何防止缓存击穿? 2021 年你写了多少代码?这个 Go 工具帮你统计 Go1.18 新特性:TryLock Go 泛型入门教程 程序员瑞士军刀:各种结构的转换工具 终于有 Go 版的 Elasticsearch 了 Go泛型系列:maps 包讲解 Go 1.18 中的 any 是什么? Go1.18 快讯:新的 IP 包 Go编程模式:详解函数式选项模式 Go泛型系列:slices 包讲解 Nginx 竟然也有 playground — Go 语言构建的 Go泛型系列:Go1.18 类型约束那些事 Go1.18 快讯:Module 工作区模式 Go1.18 快讯:新增的 Cut 函数太方便了 Go1.18 快讯:废弃了这个 API Go1.18 快讯:新增字符串 Clone API Go:如何获得项目根目录? Go 如何获取和设置环境变量 重磅变动:更快找到微信公众号里的Go文章 Go 这样设置版本号:我们的项目也可以 假期结束,推荐 2 本 manning 出的 Go 图书 Go Fiber 框架系列教程 04:测试应用 Go Fiber 框架系列教程 03:中间件 Go泛型系列:提前掌握Go泛型的基本使用 推荐一个 Go GUI 实战项目 Go Fiber 框架系列教程 02:详解相关 API 的使用 Go Fiber 框架系列教程 01: 和 Express 对比学习 Go Module:私有不合规库怎么解决引用问题 Go1.17 新特性:go get 变了 Go1.17 新特性:testing 包的相关变化 StackOverflow 上关于 Go select 死锁的问题 新书推荐:用 Gin 框架构建分布式应用 Go 官网要变天。。。 Gin 这是要成为 Go 官方框架? 扬眉吐气:刚刚,Go 已经默认支持泛型了 Go 1.17 新特性:Module 有哪些变化? Go 第三方库推荐:类型转换如此简单 担心密码提交到 GitHub?建议使用这个 Go 开源工具 Go 的时间格式化为什么是 2006-01-02 15:04:05? GitHub 为 Go 社区带来安全支持 Go开源项目推荐:500行代码确认请求时间花在哪 一道关于 len 函数的诡异 Go 面试题解析 厉害了我的 Go:推荐系统都有开源实现 Go1.17 新特性:新版构建约束 这个工具真好:看看你的Go项目依赖有无漏洞 网友很强大,发现了Go并发下载的Bug Rust 劝退系列 09:函数 Go项目实战:一步步构建一个并发文件下载器 这本 Go 新书挺期待的:100 个常见错误 Go 启用新的官方问答社区 这是要干嘛?!微软招 Go 编译器全职开发人员 Go1.17 快报之标准库越来越注重易用性 Go1.17 新特性之切片变数组 回顾 Go 官网的演变史 站长8年前的Go代码竟然进入大厂的项目里了 Go图书翻译:一个好消息,一个坏消息 不怕烂尾!决定组织翻译这本 Go 图书 Rust 劝退系列 08:模式匹配 一本花了2.5年写成的Go免费在线图书 被黑惨了:一句话,说明自己会 Go,咋整? Go1.16 中的新函数 signal.NotifyContext 怎么用? Go 1.17 新特性提前学之测试执行随机化 Rust 劝退系列 07:流程控制 官方的 Go 多版本管理:使用和原理 Rust新书:给你一个劝退的理由 周刊题解:常量表达式这个规则应该了解下 盘点那些使用 Go 语言的国外公司 编写了50万行Go代码是一种什么体验 Rust 劝退系列 06:常量 Uber 使用 Go 的规模这么大?!都自己定制的 Go 编译器了 Go Team Leader — rsc 大神新开源了一个库,增强模板功能 再一次看到了 Go 的节制:int128 类型要不要支持? Rust 劝退系列 05:复合数据类型 「卷」有理论依据:海勒姆定律—Go又是怎么卷的 Go 真的也可以进行 GUI 开发:还有这样的图书呢 我的 Go 语言书单 Rust 劝退系列 03:变量 我又来推荐免费 Go 新书了:一本用 Go 讲架构的书 注释竟然还有特殊用途?一文解惑 //go:linkname 指令 这个功能,公众号、微信群会不会被玩坏? 一道 Go 闭包题,面试官说原来自己答错了:面别人也涨知识 Rust 劝退系列 02:第一个 Rust 程序 Rust 劝退系列 01:打造开发环境 答应我,这次一定彻底搞懂 Go 中的类型别名
Rust 劝退系列 04:基本数据类型
2021-04-25 · via 文章列表 on polarisxu

大家好,我是站长 polarisxu。

这是 Rust 劝退系列的第 4 个教程,探讨 Rust 中的基本数据类型,或叫标量类型(scalar type)。

Rust 和 Go 一样,都是静态类型语言,这表示每个变量的类型必须明确。和 Go 类似,大多数情况下,Rust 编译器能够推断出某个值的类型,不需要我们显示指定,写起来有点类似于弱类型似语言。但有些情况下,必须明确告知编译器我们使用什么类型,在 Rust 中,这叫 「类型注解」(type annotations)。

对于类型注解,看一个常见的例子:

let guess = "42".parse().expect("Not a number!");

这是将字符串 "42" 转为数字 42。在 Go 语言中,一般这么做:

guess, err := strconv.Atoi("42")
if err != nil {
  panic(err)
}

但上面的 Rust 代码会报错:

error[E0282]: type annotations needed
 --> src/main.rs:2:9
  |
2 |     let guess = "42a".parse().expect("Not a number!");
  |         ^^^^^^ consider giving `guess` a type

这和 Go 还是不太一样。Go 中很多时候,数值类型会是 int。

为了修复这个问题,我们需要为 number 指定一个类型,比如 u32。

let guess: u32 = "42".parse().expect("Not a number!");

吐槽:在 Rust 中,类型注解和 Go 中一样,放在变量后面。但 Rust 中变量和类型直接非得加一个冒号(:),而且一般冒号紧跟着变量名(rustfmt 的建议)。不知道冒号有啥特殊需要?!

Rust 内置如下基本数据类型:

  • 整数类型
    • 有符号整数:i8、i16、i32、i64、i128、isize
    • 无符号整数:u8、u16、u32、u64、u128、usize
  • 浮点类型:f32、f64
  • 布尔型:bool
  • 字符型:char

01 整数类型

将整数类型整理为一张表,如下:(用 Go 语言对应的类型作对比)

长度 有符号 无符号 Go 有符号 Go 无符号
8-bit i8 u8 int8 uint8
16-bit i16 u16 int16 uint16
32-bit i32 u32 int32 uint32
64-bit i64 u64 int64 uint64
128-bit i128 u128 - -
arch isize usize int uint

吐槽:有时候 Rust 真的很节省,int、uint 直接省略为 i、u,function 省略为 fn。但有时候又很繁琐(不简洁),比如前面说到的变量和类型之间的冒号。。。

这里用 u、i 的形式,也需要一段时间适应。。。

两点说明:

  • Go 中没有 128 位长度的整数
  • isize 和 usize 对应 Go 中的 int 和 uint,它们的长度依赖运行程序的计算机架构:64 位架构上它们是 64 位的, 32 位架构上它们是 32 位的

在 Go 中,整型变量默认类型是 int,以下代码可以证明这一点:

x := 32
fmt.Printf("%T\n", i)
// 输出:int

那 Rust 中默认是什么类型呢?

我想在 Rust 中找到一种办法,打印变量类型,网上找到了这样的办法(有点挫):

// 打印变量类型的函数。该函数看不懂先放着。
fn print_type_of<T>(_: &T) {
		println!("{}", std::any::type_name::<T>())
}

fn main() {
    let x = 32;
    print_type_of(&x);
  	// 输出:i32
}

可见 Rust 中整型变量默认类型是 i32(即使在 64 位机器上,也是 i32)。这一定程度上说明,在 Go 中,整数一般建议用 int 类型;而 Rust 中,一般建议用 i32 类型。(所以,为什么开头的 parse 不能默认推断为 i32 类型呢?怕溢出?)

更智能的类型推断

上文说 Rust 和 Go 一样,支持类型推断。不过 Rust 的推断更智能,怎么个智能法?看下面的代码:

// 打印变量类型的函数
fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

fn main() {
    let x = 32;
    let y: i8 = x;
    print_type_of(&x);
    print_type_of(&y)
}

根据上面的讲解,x 应该是默认类型:i32。但实际上,x 和 y 的类型都是 i8。也就是说,因为 x 的类型没有显示的指定(类型注解),Rust 编译器会根据上下文(实际上是 let y: i8 = x 这句)推断出 x 的类型应该和 y 一致,即 i8。

在 Go 中,int8 和 int 是不会进行隐式转换的,Rust 也一样,必须进行显示转换。但 Rust 的智能类型推断,可以让开发者少写类型转换的代码。

比如上面代码,在 Go 语言中是行不通的:

package main

import (
	"fmt"
)

func main() {
	x := 32
	var y int8 = x
	fmt.Printf("%T\n", x)
	fmt.Printf("%T\n", y)
}

会报错:

cannot use x (type int) as type int8 in assignment

也就是说,Go 中的类型推断不会考虑上下文,因此没有 Rust 智能。

因为编译器的强大,VSCode 中(安装 rust-analyzer)会有类型提示,这样上面的 print_type_of 函数也不需要了。做了一个动图,注意上面 x 的类型变化:

此外,isize 和 usize 类型一般用作某些集合的索引,以后文章会看到。

关于各种类型的表示范围我不列出了,因为这个系列不是为无编程经验的人准备的。这个系列更多是为 Go 爱好者准备的 Rust 教程,因此和 Go 一致的地方可能不会讲。

02 浮点类型

和 Go 一样,Rust 也有两种浮点数类型:f32 和 f64,对应 Go 中的 float32 和 float64。和 Go 一样,默认类型是 f64,可以通过类型注解指定具体的浮点类型。(采用 IEEE-754 标准表示,关于浮点数知识,可以阅读我之前写的文章 。)

一般地,整数类型和浮点类型都成为数值类型。

数值类型有一些共同的东西。比如都支持基本的数学运算。此外,除了通过类型注解指定类型,数值类型还可以在字面值后面带上类型后缀指定类型,比如:

let x = 2.0f32;	// f32 类型
let y = 32i64;	// i64 类型

03 布尔型

和 Go 语言一样,Rust 中的布尔类型使用 bool 表示(咋没用 b、bl 之类的缩写呢?哈哈哈)。有两个可能的值:true 和 false。

fn main() {
    let t = true;

    let f: bool = false; // 显式指定类型注解
}

Rust 中的 char 表示字符类型,是 Rust 的基本类型,字面值由单引号指定。

let a = 'a';
let b = '中';
let c = '🤣';

可见,Rust 中的 char 类型和 Go 中的 rune 一样,表示的是 Unicode 码点,占 4 个字节。

因为 Rust 中的字符串很复杂,而且不是基本类型,因此留在以后讲解。

05 小结

本文介绍了 Rust 中的四种基本数据类型:整型、浮点型、布尔型和字符型。其中,浮点型、布尔型和字符型分别对应 Go 中的浮点型、布尔型和 rune 类型,但整型,Go 和 Rust 有些许不一样,上文已经详细介绍了。此外,Go 中复数也是基本数据类型:complex64 和 complex128,而 Rust 中没有,复数通过第三方库实现,比如:https://crates.io/crates/easy_complex

此外,你可能会说 Go 中还有一个基本类型:byte,而 Rust 没有。其实 Go 中的 byte 只是 uint8 的别名。另外,string 在 Go 中是基本数据类型,而在 Rust 中不是。

本节内容就这些,你被劝退了吗?欢迎留言交流!