Hàm trong Rust
Hàm (function) là một khối code có tên và dùng lại được. Thay vì viết đi viết lại cùng những bước giống nhau, bạn đặt chúng vào một hàm một lần rồi gọi hàm đó bất cứ khi nào cần. Thật ra bạn đã dùng một hàm rồi: main.
Định nghĩa và gọi hàm
Phần tiêu đề “Định nghĩa và gọi hàm”Bạn định nghĩa hàm bằng fn, và gọi nó bằng cách viết tên hàm theo sau là ():
fn greet() { println!("Xin chào từ một hàm!");}
fn main() { greet(); // gọi hàm greet(); // gọi lần nữa}Kết quả:
Xin chào từ một hàm!Xin chào từ một hàm!Tham số: đưa dữ liệu vào hàm
Phần tiêu đề “Tham số: đưa dữ liệu vào hàm”Hàm trở nên hữu ích khi bạn truyền cho nó dữ liệu để xử lý. Những dữ liệu đầu vào này gọi là tham số (parameter). Trong Rust bạn bắt buộc phải ghi kiểu của từng tham số:
fn greet(name: &str) { println!("Xin chào, {name}!");}
fn main() { greet("Alice"); greet("Bob");}Kết quả:
Xin chào, Alice!Xin chào, Bob!Bạn có thể có bao nhiêu tham số tùy ý, cách nhau bằng dấu phẩy:
fn describe(name: &str, age: u32) { println!("{name} năm nay {age} tuổi");}
fn main() { describe("Ferris", 10);}Kết quả:
Ferris năm nay 10 tuổiCác giá trị bạn truyền vào được ghép với tham số theo vị trí: giá trị thứ nhất vào name, giá trị thứ hai vào age. Truyền sai thứ tự, như describe(10, "Ferris"), là lỗi biên dịch, vì các kiểu không khớp.
Trả về một giá trị
Phần tiêu đề “Trả về một giá trị”Một hàm có thể trả một giá trị về cho nơi đã gọi nó. Bạn khai báo kiểu trả về sau mũi tên ->:
fn add(a: i32, b: i32) -> i32 { a + b}
fn main() { let sum = add(3, 4); println!("3 + 4 = {sum}");}Kết quả:
3 + 4 = 7Quy tắc dấu chấm phẩy (quan trọng!)
Phần tiêu đề “Quy tắc dấu chấm phẩy (quan trọng!)”Để ý rằng a + b trong ví dụ trên không có dấu chấm phẩy. Đây là một ý tưởng then chốt của Rust:
- Một biểu thức (expression) không có dấu chấm phẩy là giá trị được trả về.
- Thêm dấu chấm phẩy sẽ biến nó thành một câu lệnh (statement) không trả về gì cả.
Vì thế đoạn này bị lỗi:
fn add(a: i32, b: i32) -> i32 { a + b; // ❌ dấu chấm phẩy nghĩa là "không trả về gì" — nhưng ta đã hứa trả về i32}Trình biên dịch sẽ báo rằng hàm lẽ ra phải trả về một i32 nhưng lại không trả. Bạn chỉ cần bỏ dấu chấm phẩy ở dòng cuối.
Ghép tất cả lại
Phần tiêu đề “Ghép tất cả lại”fn square(n: i32) -> i32 { n * n}
fn main() { let result = square(5); println!("5 bình phương là {result}");}Kết quả:
5 bình phương là 25Luyện tập
Phần tiêu đề “Luyện tập”1. Độ C sang độ F
Phần tiêu đề “1. Độ C sang độ F”Viết hàm to_fahrenheit nhận nhiệt độ theo độ C dưới dạng f64 và trả về nhiệt độ theo độ F. Công thức là c * 9.0 / 5.0 + 32.0. Gọi nó với 0, 100 và 37 độ. Gợi ý: chữ ký hàm là fn to_fahrenheit(c: f64) -> f64, và thân hàm là một biểu thức duy nhất không có dấu chấm phẩy.
Xem lời giải
fn to_fahrenheit(c: f64) -> f64 { c * 9.0 / 5.0 + 32.0}
fn main() { println!("0°C là {}°F", to_fahrenheit(0.0)); println!("100°C là {}°F", to_fahrenheit(100.0)); println!("37°C là {}°F", to_fahrenheit(37.0));}Kết quả:
0°C là 32°F100°C là 212°F37°C là 98.6°FĐể ý rằng ta truyền 0.0 chứ không phải 0. Tham số là f64, và Rust sẽ không âm thầm đổi số nguyên thành số thực giúp bạn. Khi một f64 không có phần thập phân, {} in nó ra mà không có .0, vì thế bạn thấy 32 chứ không phải 32.0.
2. Số lớn nhất trong ba số
Phần tiêu đề “2. Số lớn nhất trong ba số”Viết hàm largest(a: i32, b: i32, c: i32) -> i32 trả về số lớn nhất trong ba số. Thử với (3, 9, 4) và (-2, -8, -5). Gợi ý: if là một biểu thức trong Rust (xem bài If…Else), nên một chuỗi if / else if / else có thể làm dòng cuối của hàm.
Xem lời giải
fn largest(a: i32, b: i32, c: i32) -> i32 { if a >= b && a >= c { a } else if b >= c { b } else { c }}
fn main() { println!("{}", largest(3, 9, 4)); println!("{}", largest(-2, -8, -5));}Kết quả:
9-2Không nhánh nào kết thúc bằng dấu chấm phẩy. Mỗi nhánh là một biểu thức, cả chuỗi if trả về một trong số chúng, và đó trở thành giá trị trả về. Dùng >= thay vì > đảm bảo khi có hai số bằng nhau, hàm vẫn trả về một giá trị.
Tóm tắt
Phần tiêu đề “Tóm tắt”- Định nghĩa hàm bằng
fn, gọi hàm bằngname(). - Tham số là đầu vào; mỗi tham số cần có kiểu:
fn greet(name: &str). - Khai báo kiểu trả về bằng
-> Type. - Biểu thức cuối cùng không có dấu chấm phẩy là giá trị trả về.
return value;cũng được, nhưng thường chỉ dùng khi muốn trả về sớm.
Kiểm tra nhanh
Phần tiêu đề “Kiểm tra nhanh”Kiểm tra nhanh
1. Trong Rust, bạn có cần ghi kiểu cho từng tham số của hàm không?
2. Khai báo kiểu trả về của hàm như thế nào?
3. Điều gì khiến a + b (không có dấu chấm phẩy) ở cuối hàm trở thành giá trị trả về?
4. Định nghĩa hàm ở trên hay ở dưới chỗ gọi nó (ví dụ trên hay dưới main) có quan trọng không?
Điểm: 0 / 4
Đọc thêm
Phần tiêu đề “Đọc thêm”- Functions — The Rust Book (tiếng Anh): chương chính thức về tham số, giá trị trả về, và câu lệnh so với biểu thức.
- Statements and Expressions — The Rust Book (tiếng Anh): nhìn kỹ hơn vào ý tưởng đằng sau quy tắc dấu chấm phẩy.
- Functions — Rust by Example (tiếng Anh): các ví dụ chạy được, gồm cả
returnsớm và hàm không trả về gì. - Functions — The Rust Reference (tiếng Anh): các quy tắc chính xác về cách định nghĩa hàm, khi bạn muốn đọc chi tiết.
- Từ khóa
fn— tài liệu thư viện chuẩn (tiếng Anh): tóm tắt ngắn về cú pháp hàm, kèm ví dụ.