Rust - Mảng
Trong chương này, chúng ta sẽ tìm hiểu về một mảng và các tính năng khác nhau liên quan đến nó. Trước khi tìm hiểu về mảng, chúng ta hãy xem mảng khác với một biến như thế nào.
Các biến có những hạn chế sau:
Các biến có bản chất vô hướng. Nói cách khác, một khai báo biến chỉ có thể chứa một giá trị duy nhất tại một thời điểm. Điều này có nghĩa là để lưu trữ n giá trị trong một chương trình sẽ cần khai báo n biến. Do đó, việc sử dụng các biến là không khả thi khi người ta cần lưu trữ một bộ sưu tập giá trị lớn hơn.
Các biến trong chương trình được cấp phát bộ nhớ theo thứ tự ngẫu nhiên, do đó gây khó khăn cho việc truy xuất / đọc các giá trị theo thứ tự khai báo của chúng.
Mảng là một tập hợp các giá trị đồng nhất. Nói một cách đơn giản, mảng là một tập hợp các giá trị của cùng một kiểu dữ liệu.
Các tính năng của một mảng
Các tính năng của một mảng được liệt kê dưới đây:
Khai báo mảng cấp phát các khối bộ nhớ tuần tự.
Mảng là tĩnh. Điều này có nghĩa là một mảng sau khi được khởi tạo sẽ không thể thay đổi kích thước.
Mỗi khối bộ nhớ đại diện cho một phần tử mảng.
Các phần tử của mảng được xác định bởi một số nguyên duy nhất được gọi là chỉ số con / chỉ số của phần tử.
Việc điền các phần tử mảng được gọi là khởi tạo mảng.
Các giá trị phần tử mảng có thể được cập nhật hoặc sửa đổi nhưng không thể bị xóa.
Khai báo và Khởi tạo Mảng
Sử dụng cú pháp dưới đây để khai báo và khởi tạo một mảng trong Rust.
Cú pháp
//Syntax1
let variable_name = [value1,value2,value3];
//Syntax2
let variable_name:[dataType;size] = [value1,value2,value3];
//Syntax3
let variable_name:[dataType;size] = [default_value_for_elements,size];
Trong cú pháp đầu tiên, kiểu của mảng được suy ra từ kiểu dữ liệu của phần tử đầu tiên của mảng trong quá trình khởi tạo.
Minh họa: Mảng đơn giản
Ví dụ sau chỉ định rõ ràng kích thước và kiểu dữ liệu của mảng. Các {:}! Cú pháp của println () chức năng được sử dụng để in tất cả các giá trị trong mảng. Hàm len () được sử dụng để tính toán kích thước của mảng.
fn main(){
let arr:[i32;4] = [10,20,30,40];
println!("array is {:?}",arr);
println!("array size is :{}",arr.len());
}
Đầu ra
array is [10, 20, 30, 40]
array size is :4
Minh họa: Mảng không có kiểu dữ liệu
Chương trình sau khai báo một mảng gồm 4 phần tử. Kiểu dữ liệu không được chỉ định rõ ràng trong khi khai báo biến. Trong trường hợp này, mảng sẽ có kiểu số nguyên. Hàm len () được sử dụng để tính toán kích thước của mảng.
fn main(){
let arr = [10,20,30,40];
println!("array is {:?}",arr);
println!("array size is :{}",arr.len());
}
Đầu ra
array is [10, 20, 30, 40]
array size is :4
Minh họa: Giá trị mặc định
Ví dụ sau tạo một mảng và khởi tạo tất cả các phần tử của nó với giá trị mặc định là -1 .
fn main() {
let arr:[i32;4] = [-1;4];
println!("array is {:?}",arr);
println!("array size is :{}",arr.len());
}
Đầu ra
array is [-1, -1, -1, -1]
array size is :4
Minh họa: Mảng với vòng lặp for
Ví dụ sau lặp qua một mảng và in các chỉ mục và giá trị tương ứng của chúng. Vòng lặp truy xuất các giá trị từ chỉ số 0 đến 4 (chỉ số của phần tử mảng cuối cùng).
fn main(){
let arr:[i32;4] = [10,20,30,40];
println!("array is {:?}",arr);
println!("array size is :{}",arr.len());
for index in 0..4 {
println!("index is: {} & value is : {}",index,arr[index]);
}
}
Đầu ra
array is [10, 20, 30, 40]
array size is :4
index is: 0 & value is : 10
index is: 1 & value is : 20
index is: 2 & value is : 30
index is: 3 & value is : 40
Hình minh họa: Sử dụng hàm iter ()
Hàm iter () tìm nạp các giá trị của tất cả các phần tử trong một mảng.
fn main(){
let arr:[i32;4] = [10,20,30,40];
println!("array is {:?}",arr);
println!("array size is :{}",arr.len());
for val in arr.iter(){
println!("value is :{}",val);
}
}
Đầu ra
array is [10, 20, 30, 40]
array size is :4
value is :10
value is :20
value is :30
value is :40
Minh họa: Mảng có thể thay đổi
Các mứt từ khóa có thể được sử dụng để khai báo một mảng có thể thay đổi. Ví dụ sau khai báo một mảng có thể thay đổi và sửa đổi giá trị của phần tử mảng thứ hai.
fn main(){
let mut arr:[i32;4] = [10,20,30,40];
arr[1] = 0;
println!("{:?}",arr);
}
Đầu ra
[10, 0, 30, 40]
Truyền Mảng dưới dạng Tham số cho Hàm
Một mảng có thể được truyền theo giá trị hoặc tham chiếu đến các hàm.
Minh họa: Truyền theo giá trị
fn main() {
let arr = [10,20,30];
update(arr);
print!("Inside main {:?}",arr);
}
fn update(mut arr:[i32;3]){
for i in 0..3 {
arr[i] = 0;
}
println!("Inside update {:?}",arr);
}
Đầu ra
Inside update [0, 0, 0]
Inside main [10, 20, 30]
Minh họa: Qua tham khảo
fn main() {
let mut arr = [10,20,30];
update(&mut arr);
print!("Inside main {:?}",arr);
}
fn update(arr:&mut [i32;3]){
for i in 0..3 {
arr[i] = 0;
}
println!("Inside update {:?}",arr);
}
Đầu ra
Inside update [0, 0, 0]
Inside main [0, 0, 0]
Khai báo mảng và hằng số
Chúng ta hãy xem xét một ví dụ dưới đây để hiểu khai báo mảng và các hằng số.
fn main() {
let N: usize = 20;
let arr = [0; N]; //Error: non-constant used with constant
print!("{}",arr[10])
}
Trình biên dịch sẽ dẫn đến một ngoại lệ. Điều này là do độ dài của mảng phải được biết tại thời điểm biên dịch. Ở đây, giá trị của biến "N" sẽ được xác định trong thời gian chạy. Nói cách khác, các biến không thể được sử dụng để xác định kích thước của một mảng.
Tuy nhiên, chương trình sau hợp lệ:
fn main() {
const N: usize = 20;
// pointer sized
let arr = [0; N];
print!("{}",arr[10])
}
Giá trị của một mã định danh có tiền tố từ khóa const được xác định tại thời điểm biên dịch và không thể thay đổi trong thời gian chạy. usize có kích thước bằng con trỏ, do đó kích thước thực của nó phụ thuộc vào kiến trúc mà bạn đang biên dịch chương trình của mình.