!
means that you’re calling a macro instead of a normal function.let
statement, which is used to create a variable.mut
before the variable name to make a variable mutable.&
indicates that is a reference, which gives you a way to let multiple parts of your code access one piece of data without needing to copy that data into memory multiple times.mut
with constants.const
keyword, the type of the value must be annotated.mut
. By using let
, we can perform a few transformations on a value but have the variable be immutable after those transformations have been completed. We can change the type of the value but reuse the same name.i8
u8
i16
u16
i32
u32
i64
u64
i128
u128
isize
usize
--release
flag, Rust does not include checks for integer overflow that cause panics.f32
and f64
. The default type is f64
because on modern CPUs it’s roughly the same speed as f32
but is capable of more precision.true
and false
. Booleans are one byte in size.char
type is the language’s most primitive alphabetic type. char
literals are specified with single quotes. Rust’s char
type is four bytes in size and represents a Unicode Scalar Value..
) followed by the index of the value we want to access. {}
, is an expression. Expressions do not include ending semicolons.return
keyword and specifying a value.if
is an expression. You must be explicit and always provide if
with a Boolean as its condition. The values that have the potential to be results from each arm of the if
must be the same type.loop
, while
, and for
.loop
keyword tells Rust to execute a block of code over and over again forever or until you explicitly tell it to stop. break
expression you use to stop the loop; that value will be returned out of the loop so you can use it.for
loop and execute some code for each item in a collection.drop
automatically at the closing curly bracket.String
, not just the stack data, we can use a common method called clone
.Copy
trait that we can place on types like integers that are stored on the stack. If a type implements the Copy
trait, an older variable is still usable after assignment. Rust won’t let us annotate a type with the Copy
trait if the type, or any of its parts, has implemented the Drop
trait. Any group of simple scalar values can implement Copy
. Here are some of the types that implement Copy
:u32
.bool
, with values true
and false
.f64
.char
.Copy
. For example, (i32, i32)
implements Copy
, but (i32, String)
does not.drop
unless the data has been moved to be owned by another variable.&
is dereferencing, which is accomplished with the dereference operator, *
. String
. Internally, the slice data structure stores the starting position and the length of the slice. String slice range indices must occur at valid UTF-8 character boundaries.s
here is &str
: it’s a slice pointing to that specific point of the binary.String
makes our API more general and useful without losing any functionality.()
, the unit type. self
, which represents the instance of the struct the method is being called on.self
as the first parameter is rare; this technique is usually used when the method transforms self
into something else and you want to prevent the caller from using the original instance after the transformation.impl
blocks.Option<T>
included in the prelude.None
rather than Some
, we need to tell Rust what type of Option<T>
we have.Option<T>
, you can safely assume that the value isn’t null. This was a deliberate design decision for Rust to limit null’s pervasiveness and increase the safety of Rust code.match
Control Flow Operatormatch
allows you to compare a value against a series of patterns and then execute code based on which pattern matches. Patterns can be made up of literal values, variable names, wildcards, and many other things._
pattern will match any value. if let
if let
syntax lets you combine if
and let
into a less verbose way to handle values that match one pattern while ignoring the rest. if let
as syntax sugar for a match
that runs code when the value matches one pattern and then ignores all other values.cargo new XX
command will give us a package.crate
.crate
.self
, super
, or an identifier in the current module.pub
keyword on a module only lets code in its ancestor modules refer to it.pub
before a struct definition, we make the struct public, but the struct’s fields will still be private.use
Keyworduse
keyword.use
also check privacy.use
and a relative path.use
so we have to specify the parent module when calling the function makes it clear that the function isn’t locally defined while still minimizing repetition of the full path. On the other hand, when bringing in structs, enums, and other items with use
, it’s idiomatic to specify the full path. as
and a new local name, or alias, for the type.use
keyword, the name available in the new scope is private. To enable the code that calls our code to refer to that name as if it had been defined in that code’s scope, we can combine pub
and use
. std
) is also a crate that’s external to our package. The name of the standard library crate is std
.*
, the glob operator. Glob can make it harder to tell what names are in scope and where a name used in your program was defined.mod xxx
rather than using a block tells Rust to load the contents of the module from another file with the same name as the module. mod
keyword declares modules, and Rust looks in a file with the same name as the module for the code that goes into that module.str
that is usually seen in its borrowed form &str
.String
type, which is provided by Rust’s standard library rather than coded into the core language, is a growable, mutable, owned, UTF-8 encoded string type.OsString
, OsStr
, CString
, and CStr
. +
operator or the format!
macro to concatenate String
values.+
operator uses the add
method, whose signature looks something like this:&String
argument into a &str
. String
is a wrapper over a Vec<u8>
.[]
with a range to create a string slice containing particular bytes:chars
method. The bytes
method returns each raw byte.HashMap<K, V>
stores a mapping of keys of type K
to values of type V
. Copy
trait, like i32
, the values are copied into the hash map. For owned values like String
, the values will be moved and the hash map will be the owner of those values.or_insert
method on Entry
is defined to return a mutable reference to the value for the corresponding Entry
key if that key exists, and if not, inserts the parameter as the new value for this key and returns a mutable reference to the new value. Result<T, E>
for recoverable errors and the panic!
macro that stops execution when the program encounters an unrecoverable error.panic
!panic!
macro executes, your program will print a failure message, unwind and clean up the stack, and then quit.panic = 'abort'
to the appropriate [profile]
sections in your Cargo.toml file. RUST_BACKTRACE
environment variable to get a backtrace of exactly what happened to cause the error. Result
Result
enum and its variants have been brought into scope by the prelude.?
placed after a Result
value is defined to work in almost the same way as the match
expressions. If the value of the Result
is an Ok
, the value inside the Ok
will get returned from this expression, and the program will continue. If the value is an Err
, the Err
will be returned from the whole function as if we had used the return
keyword.?
operator called on them go through the from
function. When the ?
operator calls the from
function, the error type received is converted into the error type defined in the return type of the current function. As long as each error type implements the from
function to define how to convert itself to the returned error type, the ?
operator takes care of the conversion automatically.?
operator in a function that returns Result
or Option
or another type that implements std::ops::Try
. The main
function is special:panic!
or Not to panic!
panic
for examples, prototype code, and tests.unwrap
when you have some other logic that ensures the Result
will have an Ok
value, but the logic isn’t something the compiler understands.panic!
and alert the person using your library to the bug in their code so they can fix it during development. Similarly, panic!
is often appropriate if you’re calling external code that is out of your control and it returns an invalid state that you have no way of fixing.Result
than to make a panic!
call.