Trên đường thiên lý: từ From tới Option
TIL
498
Rust
27
Rust 1.12.0
1
White

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

fn plus_5(x: Option<i32>) -> 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ỏ, thay vì truyền kiểu Option vào thì truyền trực tiếp kiểu i32 được không?, chắc chắn là báo lỗi ngay.

fn plus_5(x: Option<i32>) -> i32 {
    x.unwrap_or(0) + 5
}
fn main() {
    assert_eq!(15, plus_5(10));
}

Compile: expected enum `std::option::Option`, found in, nhưng chúng ta muốn vừa truyền kiểu Option được vừa truyền i32 được, vậy làm thế nào ?

Research chút xíu, vào enum Options tìm một số điều mới mẻ ở bản 1.12 nhé. Nhấn Command + F ở chrome và gõ 1.12.0, tìm được gì nào, một implement đã được thêm vào:

impl<T> From<T> for Option<T>1.12.0
    fn from(val: T) -> Option<T>

Performs the conversion.

Nghĩa là sao nhỉ? Chúng ta có thể chuyển từ 1 type T thành Option<T>
Nếu chúng ta có Option::from(10) thì nó sẽ trả về Some(10)

Trở lại ví dụ trên, thay đổi chút về argument truyền vào

fn plus_5<T>(x: T) -> i32
    where Option<i32>: From<T>
{
    Option::from(x).unwrap_or(0) + 5
}
fn main() {
    assert_eq!(15, plus_5(10));
}

Lần lượt truyền kiểu type là i32Option vào hàm trên tất cả điều compile thành công, có lẻ nên dừng lại tại đây. Như vậy đã là quá đủ :troll:

Nhưng mà thấy nó có cái where trong đó thấy vẫn chưa tốt lắm nên tìm cách rút ngắn nó nửa. Chúng ta vẫn muốn viết theo kiểu: viết 1 lần dùng mãi mãi. Vậy chìa khoá để tìm ra là gì,, quay trở lại với trait From chúng ta có thể thấy
std::convert::From nó thuộc std::convert, vậy đi lần ra chổ convert xem có cái gì hấp dẫn không nhé.

From<U> for T implies Into<T> for U

Tiếp tục tìm đến trait Into, thấy được 1 list các Implementors trong đó có

impl<T, U> Into<U> for T where U: From<T>

Trong trường hợp của chúng ta là Option, nhưng giờ thì Option đã implement trait From, nên chúng ta có thể viết lại đơn giản hơn:

fn plus_5<T: Into<Option<i32>>>(x: T) -> i32 {
    x.into().unwrap_or(0) + 5
}
fn main() {
    assert_eq!(15, plus_5(Some(10)));
    //assert_eq!(15, plus_5(10));
}
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 1 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 12 tháng 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 11 tháng 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 1 năm trước
3 3
{{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á!