Today, let’s explore some commonly used data types in Rust.
Integer Types
- • Signed integers: i8, i16, i32, i64, i128, isize
- • Unsigned integers: u8, u16, u32, u64, u128, usize
These numeric types can be converted to each other using the <span>as</span> keyword:
let a: i32 = 1;
// i32 -> i64
let b: i64 = a as i64;
// i64 -> i32
let c: i32 = b as i32;
Note: Converting from larger to smaller types may cause overflow.
Floating Point Types
f32, f64
Boolean Type
bool: Values are true or false.
You can use
<span>as</span>or<span>into</span>to convert bool to a number, but not the other way around.
Character Type
char: Unicode character, fixed at 4 bytes.
let c: char = 'A';
let c: char = '😊';
String Type
String: A mutable-length string encoded in UTF-8, allowing dynamic addition, modification, and deletion of characters.
In addition, there are other string types, such as: <span>OsString</span> and <span>CString</span>, which will be understood in detail later.
String Slice
str: Since it is a slice type, and slice types have variable sizes, in most cases, we use its reference, which is <span>&str</span>. If you directly use <span>str</span> to define a string, it will result in an error:
// Will receive 2 errors
// 1. expected `str`, found `&str`
// 2. doesn't have a size known at compile-time
let s: str = "hello";
For string slices, it is easy to implement slicing operations, for example: <span>&s[..3]</span>
🤔 What is a slice?
- • A slice is a reference type in Rust that allows access to a portion of a contiguous sequence.
- • A slice does not own the data, it merely borrows existing data.
- • A slice is a dynamically sized type (DST) and must be used through a reference.
In simple terms, a slice is used to access part of a type’s data, its size is not fixed, and cannot be determined at compile time. Rust requires all types to have their size determined at compile time, so for slice data, you can only access it using its reference or pointer, as the size of a reference is known at compile time.
Tuple
A tuple is a fixed-length ordered collection that can contain elements of different types. For example: <span>(1, "hello", 3.14)</span>.
Note a special tuple: <span>()</span>, which has no elements and can be used as a return value for methods that do not need to return a value, and can usually be omitted, such as: <span>fn a() -> ()</span> → <span>fn a()</span>
Array
An array is a fixed-length ordered collection that can only contain elements of the same type. For example: <span>[1, 2, 3]</span>.
Array Slice
&[T]: An array slice is a reference used to access part of an array’s data without taking ownership. For example: <span>&arr[start..end]</span>: from start to end-1<span>&arr[start..]</span>: from start to the end of the array<span>&arr[..end]</span>: from the beginning to end-1<span>&arr[..]</span>: the entire array slice
<span>&String</span> and <span>&str</span> Compatibility
Rust can automatically convert from <span>&String</span> to <span>&str</span>, for example in this case:
fn hello(name: &str){
println!("{}", name);
}
// Passing a reference of String
hello(&String::from("world"));
// Passing a literal, which is of type &str
hello("world");
Whether passing <span>&String</span> or <span>&str</span> is valid, because at compile time the compiler will automatically dereference <span>&String</span> to <span>&str</span>.
impl ops::Deref for String {
type Target = str;
#[inline]
fn deref(&self) -> &str {
self.as_str()
}
}
Therefore, when using strings as function parameters, it is preferable to use <span>&str</span> instead of <span>String</span>.