Bàn về cách xử lý lỗi của Rust
Rust
27
White

Giang Nguyen viết ngày 07/10/2016

alt text

Chém gió đầu bài

Giống hầu hết các ngôn ngữ khác, điều có phần handle khi có error xảy ra. Có thể là trả về error hoặc exceptions nó. Với Rust thì sẽ có chút khác biệt. Vậy nó là gì ? Cùng lướt qua nhá.

1. Cơ bản

fn is_number_greater_than_5(n: i32) -> bool {
   if n < 5 {
       panic!("Try other number");
   }
   n > 5
}
fn main() {
    is_number_greater_than_5(4);
}

Bạn có thể nghĩ đơn giản error handling là quá trình liên tiếp kiểm tra các trường hợp để xác định tính đúng đắn của nó. Uh! cũng đúng, nhưng không tốt lắm, nếu xét ví dụ trên có thể dể nhận ra là chương trình đang có một lỗi tìm ẩn là ở cái macro panic.

Nếu compile và run nó thì điều gì sẽ xảy ra ?

Bum! Errorrrrrrrrrrrrrrrrrrrrrrr

thread 'main' panicked at 'Try other number', src/main.rs:3

Vậy bạn có thể hiểu được cái macro panic rồi nhỉ. Nếu vậy chương trình chúng ta có thể panic bất kỳ lúc nào, nếu gặp trường hợp như thế gặp mình thì mình sẽ soạn lại CV ngay và luôn :smile: .

Nếu thế thì sửa lại hàm trên thay vì để panic vào thì giờ xoá nó luôn

fn is_number_greater_than_5(n: i32) -> bool {
    n > 5
}
fn main() {
    assert_eq!(false, is_number_greater_than_5(4));
}

Nhìn thì tốt, chương trình vẫn chạy ok, nhưng có vẻ cách làm của chúng ta chỉ áp dụng được cho bài toán đơn giản, nếu xét về bài toán:

Open file, kế tiếp đọc nội dung file đó, rồi parse content đó thành dạng i32 vậy nếu chúng ta dùng cách ase analysis thì có quá nhiều case,
và điều quan trọng là nếu đưa cái hàm đó cho người khác dùng thì nếu họ muốn thay đổi cái thông bao lỗi thì thế nào ? chỉ còn cách thay đổi cái hàm đó thôi.

Ummmm! Bỏ qua cái trường hợp open file đó, chúng ta sẽ quay lại với nó sau :smile:.

Lấy thêm một ví dụ nửa, lần này là parse từ str sang i32.

    fn main() {
        let parsed_str = "5".parse::<i32>().unwrap();
        assert_eq!(5, parsed_str);
    }

"5" là &str không phải là String đâu. Nếu nhìn vào ví dụ trên thì sẽ thấy có cái hàm lạ lạ là unwrap, vậy nó là gì ?, let me show

pub fn unwrap(self) -> T {
        match self {
            Some(val) => val,
            None => panic!("called `Option::unwrap()` on a `None` value"),
        }
    }

Vì hàm parse<T> trả về là kiểu Options nên ta có thể mò tới enum Options để xem function của nó có gì.
well, cũng có panic đấy, nếu compile đoạn code trên thì không có lỗi xảy ra, nhưng nếu ta thay "5" thành một str khác chẳn hạn như "hello world" nếu compile lại, thì văng ngay và luôn cái lỗi và crash luôn chương trình:

 thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseIntError { kind: InvalidDigit }', ../src/libcore/result.rs:788

Hiểu đơn giản thì unwrap sẽ kiểm tra xem có giá trị không, có thì trả về, còn không thì panic nó ra. Cho nên việc dùng unwrap phải cận thận, chương trình có thể panic bất kỳ lúc nào!

Quay trở lại, unwrap nó là hàm được implement ở đâu. Nếu nhìn vào lỗi và lần ra thì nó được implement ở 2 enum là OptionResult. Nên chúng ta cần tìm hiểu sơ sơ về 2 thằng này, để sau này còn dùng. Trong bài viết sau mình sẽ giới thiệu về 2 thằng này để có cách nhìn tổng quát, đây là 2 enum được dùng như là kiểu trả về của function.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Giang Nguyen

20 bài viết.
34 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
30 5
(Ảnh) Hai ngày nay mình đã tìm hiểu về Amazon S3, Cloudfront và Letsencrypt để xây dựng 2 trang web static, thứ nhất là trang chủ của (Link) và t...
Giang Nguyen viết gần 2 năm trước
30 5
White
9 0
Đôi dòng về ID3 (Ảnh) Nếu bạn nào chưa biết thì có thể đọc phần này, hoặc biết rồi thì có thể next tới phần kế tiếp nhé. 1. Giới thiệu Như hì...
Giang Nguyen viết hơn 1 năm trước
9 0
White
8 0
Type Result Type trên dùng để làm gì? Result được dùng cho những trường hợp chúng ta muốn return lại một giá trị nào đó (Ok) hoặc propagating erro...
Giang Nguyen viết hơn 1 năm trước
8 0
Bài viết liên quan
White
3 3
Hôm nay tự viết lại cái note này về quá trình học Rust, xem như là tự giúp mình nhớ sâu và rõ hơn về Rust. Note này sẽ ngắn gọn hơn bản (Link). Sơ...
Giang Nguyen viết gần 2 năm trước
3 3
White
0 0
fn plus_5(x: Option) i32 { x.unwrap_or(0) + 5 } fn main() { assert_eq(15, plus_5(Some(10))); } Compile không lỗi, thay đổi chút xíu nhỏ, ...
Giang Nguyen viết 2 năm trước
0 0
White
2 4
Cài đặt Rust trên Arch Linux Việc cài đặt Rust trên môi trường Arch Linux khá là đơn giản. pacman có sẵn gói (Link) và (Link), bạn có thể chọn các...
Huy Trần viết hơn 1 năm trước
2 4
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
20 bài viết.
34 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!