RUST的数据类型

RUST的数据类型Rust中的每个值都具有特定的数据类型,该值告诉Rust指定了哪种数据,从而知道如何使用该数据。error: aborting due to p

大家好,欢迎来到IT知识分享网。RUST的数据类型

Rust中的每个值都具有特定的数据类型,该值告诉Rust指定了哪种数据,从而知道如何使用该数据。我们将研究两个数据类型子集:标量和复合。

请记住,Rust是一种静态类型的语言,这意味着它必须在编译时知道所有变量的类型。编译器通常可以根据值以及如何使用它来推断我们要使用的类型。在当许多类型是可能的,比如当我们转换的情况下String,使用数字式parse的在“猜猜相较于秘密号码”中第2章部分,我们必须添加类型注释,如下所示:

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

如果我们不在此处添加类型注释,Rust将显示以下错误,这意味着编译器需要我们提供更多信息,以了解我们要使用哪种类型:

$ cargo build

Compiling no_type_annotations v0.1.0 (file:///projects/no_type_annotations)

error[E0282]: type annotations needed

–> src/main.rs:2:9

|

2 | let guess = “42”.parse().expect(“Not a number!”);

| ^^^^^ consider giving `guess` a type

error: aborting due to previous error

For more information about this error, try `rustc –explain E0282`.

error: could not compile `no_type_annotations`.

To learn more, run the command again with –verbose.

您会看到其他数据类型的不同类型注释。

标量类型

标量类型表示一个单一的值。Rust具有四种主要的标量类型:整数,浮点数,布尔值和字符。您可能会从其他编程语言中识别这些。让我们进入它们在Rust中的工作方式。

整数类型

一个整数是没有小数部分的数。在第2章中,我们使用了一种整数u32类型。此类型声明指示与其关联的值应为占用32位空间的无符号整数(有符号整数类型以开头i,而不是u)。表3-1显示了Rust中的内置整数类型。Signed和Unsigned列中的每个变体(例如i16)都可以用来声明整数值的类型。

表3-1:Rust中的整数类型

长度签未签名8位i8u816位i16u1632位i32u3264位i64u64128位i128u128拱isizeusize

每个变体可以是有符号的也可以是无符号的,并且具有明确的大小。 带符号和无符号是指数字是负数还是正数,换句话说,数字是否需要带有正负号(带正负号),或者数字将永远是正数,因此可以不带正负号来表示(未签名)。这就像在纸上写数字一样:当符号很重要时,数字上会显示加号或减号。但是,可以放心地假设数字为正数时,它不会显示任何符号。带符号的数字使用二进制补码表示存储。

每个带符号的变体可以存储-(2 n-1)到2 n-1-1之间的数字,其中n是变体使用的位数。因此,一个 i8可从存储号码- (2 7)至2 7 – 1,其等于-128到127无符号的变体可以存储从0编号,以2 Ñ – 1,所以u8可以从0存储编号,以2 8 – 1,等于0到255。

此外,isize和usize类型取决于您的程序所运行的计算机的类型:如果您使用的是64位体系结构,则为64位;如果您使用的是32位体系结构,则为32位。

您可以用表3-2中所示的任何形式编写整数文字。请注意,除了字节文字外,所有数字文字都允许使用类型后缀(例如 57u8)和_可视分隔符(例如)1_000。

表3-2:Rust中的整数文字

数字文字例小数98_222十六进制0xff八进制0o77二元0b1111_0000字节(u8仅)b’A’

那么,您如何知道要使用哪种类型的整数?如果不确定,Rust的默认值通常是不错的选择,整数类型的默认值是i32:即使在64位系统上,这种类型通常也是最快的。在为某种集合建立索引时,您将使用isize或的主要情况usize。

整数溢出

假设您有一个类型u8可以容纳0到255之间的值的变量。如果尝试将变量更改为该范围之外的值(例如256),则会发生整数溢出。Rust有一些有趣的规则涉及此行为。在调试模式下进行编译时,Rust包括整数溢出检查,如果发生此行为,整数溢出会使程序在运行时惊慌。当程序错误退出时,Rust使用惊慌一词。我们将在第9章的“无法恢复的错误panic!”部分中更深入地讨论恐慌。

当你在释放模式编译–release标志,锈也 未包括整数溢出是造成恐慌的检查。相反,如果发生溢出,Rust将执行二进制补码。简而言之,大于类型可以保持的最大值的值“环绕”到类型可以保持的最小值。在a的情况下u8,256变为0,257变为1,依此类推。该程序不会出现紧急情况,但是该变量的值可能不是您期望的值。依赖整数溢出的包装行为被视为错误。如果要显式包装,则可以使用标准库类型Wrapping。

浮点类型

Rust对于浮点数也有两种原始类型,即带小数点的数字。Rust的浮点类型为f32和f64,大小分别为32位和64位。默认类型是f64 因为在现代CPU上,它的速度与之大致相同,f32但具有更高的精度。

这是一个显示浮点数的示例:

文件名:src / main.rs

fn main() {

let x = 2.0; // f64

let y: f32 = 3.0; // f32

}

浮点数根据IEEE-754标准表示。该 f32类型是单精度浮点,并且f64具有双精度。

数值运算

Rust支持您期望所有数字类型的基本数学运算:加,减,乘,除和余数。以下代码显示了如何在let语句中使用每个代码:

文件名:src / main.rs

fn main() {

// additionlet sum = 5 + 10;

// subtractionlet difference = 95.5 – 4.3;

// multiplicationlet product = 4 * 30;

// divisionlet quotient = 56.7 / 32.2;

// remainderlet remainder = 43 % 5;

}

这些语句中的每个表达式都使用数学运算符并求值为单个值,然后将其绑定到变量。附录B包含Rust提供的所有运算符的列表。

布尔类型

与大多数其他编程语言一样,Rust中的布尔类型具有两个可能的值:true和false。布尔值的大小为1个字节。Rust中的布尔类型使用指定bool。例如:

文件名:src / main.rs

fn main() {

let t = true;

let f: bool = false; // with explicit type annotation

}

使用布尔值的主要方法是通过条件,例如if 表达式。我们将if在“控制流”部分中介绍表达式在Rust中的工作方式。

角色类型

到目前为止,我们仅处理数字,但是Rust也支持字母。Rust的 char类型是该语言最原始的字母类型,下面的代码显示了一种使用它的方式。(请注意,char文字是用单引号指定的,而字符串文字是使用双引号的。)

文件名:src / main.rs

fn main() {

let c = ‘z’;

let z = ‘ℤ’;

let heart_eyed_cat = ”;

}

Rust的char类型为4个字节,代表Unicode标量值,这意味着它可以代表的不仅仅是ASCII。重音字母;中文,日文和韩文字符;表情符号 和零宽度空格char在Rust 中都是有效值。Unicode标值的范围从U+0000到 U+D7FF和U+E000到U+10FFFF包容性。但是,“字符”在Unicode中并不是真正的概念,因此您对“字符”是什么的直觉可能与charRust中的a 不一致。我们将 在第8章“使用字符串存储UTF-8编码文本”中详细讨论该主题。

复合类型

复合类型可以将多个值组合为一种类型。Rust有两种原始的复合类型:元组和数组。

元组类型

元组是将多种类型的多个值组合为一个复合类型的一般方法。元组的长度是固定的:声明后,它们的大小就无法增长或缩小。

我们通过在括号内编写逗号分隔的值列表来创建元组。元组中的每个位置都有一个类型,并且元组中不同值的类型不必相同。在此示例中,我们添加了可选的类型注释:

文件名:src / main.rs

fn main() {

let tup: (i32, f64, u8) = (500, 6.4, 1);

}

该变量tup绑定到整个元组,因为元组被视为单个复合元素。为了从元组中取出单个值,我们可以使用模式匹配来破坏元组值,如下所示:

文件名:src / main.rs

fn main() {

let tup = (500, 6.4, 1);

let (x, y, z) = tup;

println!(“The value of y is: {}”, y);

}

该程序首先创建一个元组并将其绑定到变量tup。然后,它使用带有图案let采取tup并把它变成三个独立的变量x,y和z。这称为解构,因为它将单个元组分为三部分。最后,程序将输出的值 y,即6.4。

除了通过模式匹配进行结构分解外,我们还可以通过使用句点(.)和要访问的值的索引直接访问元组元素。例如:

文件名:src / main.rs

fn main() {

let x: (i32, f64, u8) = (500, 6.4, 1);

let five_hundred = x.0;

let six_point_four = x.1;

let one = x.2;

}

该程序创建一个元组,x然后使用它们各自的索引为每个元素创建新变量。与大多数编程语言一样,元组中的第一个索引为0。

数组类型

收集多个值的另一种方法是使用数组。与元组不同,数组的每个元素都必须具有相同的类型。Rust中的数组与某些其他语言中的数组不同,因为Rust中的数组具有固定的长度,例如元组。

在Rust中,进入数组的值被写成用方括号括起来的逗号分隔列表:

文件名:src / main.rs

fn main() {

let a = [1, 2, 3, 4, 5];

}

当您希望将数据分配在堆栈而不是堆上时(当我们在第4章中讨论堆栈和堆时),或者要确保始终有固定数量的元素时,数组很有用。但是,数组不像矢量类型那样灵活。载体是由标准库提供一个类似集合类型是允许生长或尺寸的缩小。如果不确定使用数组还是向量,则可能应该使用向量。第8章将更详细地讨论向量。

一个程序可能需要使用数组而不是向量的示例是在一个程序中,该程序需要知道一年中各个月份的名称。这样的程序不太可能需要添加或删除月份,因此您可以使用数组,因为您知道它将始终包含12个元素:

let months = [“January”, “February”, “March”, “April”, “May”, “June”, “July”,

“August”, “September”, “October”, “November”, “December”];

您将使用方括号编写数组的类型,并且在方括号中包括每个元素的类型,分号,然后是数组中元素的数量,如下所示:

let a: [i32; 5] = [1, 2, 3, 4, 5];

在这里,i32是每个元素的类型。分号后的数字5 表示数组包含五个元素。

以这种方式编写数组的类型看起来类似于初始化数组的另一种语法:如果要创建一个数组,该数组的每个元素都包含相同的值,则可以指定初始值,后跟一个分号,然后指定长度数组放在方括号中,如下所示:

let a = [3; 5];

名为的数组a将包含5将全部设置为3初始值的元素 。这与写作相同,let a = [3, 3, 3, 3, 3];但更为简洁。

访问数组元素

数组是在堆栈上分配的单个内存块。您可以使用索引访问数组的元素,如下所示:

文件名:src / main.rs

fn main() {

let a = [1, 2, 3, 4, 5];

let first = a[0];

let second = a[1];

}

在此示例中,名为的变量first将获得值1,因为这是[0]数组中index处的值。名为的变量second将从数组中的2索引获取值[1]。

无效的数组元素访问

如果您尝试访问超出数组末尾的数组元素,会发生什么情况?假设您将示例更改为以下代码,这些代码将编译但运行时会退出并显示错误:

文件名:src / main.rs

fn main() {

let a = [1, 2, 3, 4, 5];

let index = 10;

let element = a[index];

println!(“The value of element is: {}”, element);

}

使用运行此代码将cargo run产生以下结果:

$ cargo run

Compiling arrays v0.1.0 (file:///projects/arrays)

Finished dev [unoptimized + debuginfo] target(s) in 0.31s

Running `target/debug/arrays`

thread ‘main’ panicked at ‘index out of bounds: the len is 5 but the index is 10’, src/main.rs:5:19

note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

编译没有产生任何错误,但是程序导致 运行时错误,并且没有成功退出。当您尝试使用索引访问元素时,Rust将检查您指定的索引是否小于数组长度。如果索引大于或等于数组长度,Rust将惊慌。

这是Rust实施安全原则的第一个示例。在许多低级语言中,不会执行这种检查,并且当您提供错误的索引时,可以访问无效的内存。Rust通过立即退出而不是允许内存访问并继续操作来保护您免受此类错误的侵害。第9章讨论了Rust的更多错误处理。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/46330.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信