Rust学习——TRPL-Part4
Common Programming Concepts
Variables and Mutability
By deault, variables are immutable
.
In Rust, the compiler guarantees that when you state that a value won’t change, it really won’t change.
Mutablitiy can be very useful. Just add mut
in front of the variable name.
Mutable / Immutable Trade-off
There are multiple trade-offs to consider in addition to the prevention of bugs. For example, in cases where you’re using large data structures, mutating an instance in place may be faster than copying and returning newly allocated instances. With smaller data structures, creating new instances and writing in a more functional programming style may be easier to think through, so lower performance might be a worthwhile penalty for gaining that clarity.
Differences Between Variables and Constants
Yep, 不可以更改变量的值很容易联想起C或其他编程语言中的constants。
Difference:
- Can't add
mut
with constants. Not by default but always immutable. - Using
constant
keyword instead of thelet
keyword. Type of the value must be annoted. - Constants can be declared in any scope, including the global scope.
- Constants may be set only to a constant expression, not the result of a function call or any other value that could only be computed at runtime.
Rust's naming convention for constants
Use all uppercase with underscores between words.
For example:
1
const MAX_POINTS: u32 = 100_000;
Recommended Usage:
- For values in your application domain that mutipule parts of the program might need to know about, such as the maximum number of points any player of a game
- Naming hardcoded values used throughout your program as constants for conveying the meaning and reusage.
Shadowing
We can shadow a variable by using the same variable’s name and repeating the use of the let
keyword.
Difference between shadowing and mutable variables
Variables can still be immutable and we’ll get a compile-time error if we accidentally try to reassign to this variable without using the
let
keyword. By usinglet
, we can perform a few transformations on a value but have the variable be immutable after those transformations have been completed.The other difference between mut and shadowing is that because we’re effectively creating a new variable when we use the let keyword again. We can change the type of the value but reuse the same name.
We can compile the following code:
1 |
|
The first spaces
is a string type but the second after let
, is a brand-new variable with the same name, is a number type. Shadowing thus spares us from having to come up with different names, such as spaces_str
and spaces_num
.
However, if we try to use mut
for this, we'll get a compiler-time error:
1 |
|
Not allowed to mutable a variable's type. We will get mismatched types.
Data Types
Scalar Types
A scalar type represents a single value. Rust has four primary scalar types: integers, floating-point numbers, Booleans, and characters.
Integer Types
Signed integer start with i
(from \(0\) to \(2^n-1\)) and unsigned start with u
(from \(-(2^{n-1}\) to \(2^{n-1}-1\)).
Can write integer literals in any of the forms shown bellow. Number literals can also use _
as a visual separator to make the number easier to read, such as 1_000
.
Number literals | example |
---|---|
Decimal | 98_222 |
Hex | 0xff |
Octal | 0o77 |
Binary | 0b1111_0000 |
Byte(u8 only ) |
b'A' |
If you’re unsure, Rust’s defaults are generally good places to start: integer types default to i32
. The primary situation in which you’d use isize
or usize
is when indexing some sort of collection.
Floating-Point Types
Floating-point numbers are represented according to the IEEE-754 standard. The f32
type is a single-precision float, and f64
has double precision.
The Boolean Type
The Character Type
Compound Types
Compound types
can group multiple values into one type. Rust has two primitive compound types: tuples and arrays.
The Tuple Type
Each position in the tuple has a type. Don't have to be the same.
1 |
|
The Array Type
Unlike a tuple, every element of an array must have the same type.
Arrays are useful when you want your data allocated on the stack rather than the heap (we will discuss the stack and the heap more in Chapter 4) or when you want to ensure you always have a fixed number of elements.
1 |
|
We can not write Rust code let x = (let y = 6);
(compare to x = y = 6;
in C code). The let y = 6
statement does not return a value, so there isn't anything for x
to bind to.
Expressions evaluate to something and make up most of the rest of the code that you’ll write in Rust.
Expressions can be part of statements. Single value assign to variable on the right of =
is an expression. The block that we use to create new scopes, {}
, is an expression. Calling a function is an expression.
Functions with Return Values
Declare their type after an arrow(->
). Return value of the function is synonymous with the value of the final expression in the block of the body of a function. Using return
keyword and or return the last expression implicitly.
BECAREFUL TO SEMICOLON
注意隐式返回要求是Expression,如果加上分号则认为是Statement,此时默认返回的是 empty tuple ()
,编译时会发现mismatched types
.
1 |
|
Control Flow
if
expressions and loops.
Rust if
expressions 要求值类型必须为bool
类似C中的写法会产生错误。
1 |
|
cargo run
得到的报错信息:
1 |
|
The error indicates that Rust expected a
bool
but got an integer. Unlike languages such as Ruby and JavaScript, Rust will not automatically try to convert non-Boolean types to a Boolean. You must be explicit and always provideif
with a Boolean as its condition.
Using if in a let Statement
if
也是 expression 我们可以将其用在let
右侧。
1 |
|
Pay attention:
- Blocks of code evaluate to last expression in them.
- Types need to be matched (If not, we'll get an error).
Repetition with Loops
Rust has three kinds of loops: loop
, while
, and for
.
Returning Values from Loops
One of the uses of a loop
is to retry an operation you know might fail, such as checking whether a thread has completed its job. However, you might need to pass the result of that operation to the rest of your code. To do this, you can add the value you want returned after the break
expression you use to stop the loop; that value will be returned out of the loop so you can use it, as shown here:
1 |
|
for
loop 是Rustaceans最常用的,使用迭代器,方便快捷,安全。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!