Đôi chút về 2 thằng Into và From
Rust
27
learn-rust-alone
1
White

Giang Nguyen viết ngày 24/11/2016

Liệu chúng ta có thể viết 1 function mà parameter của nó có thể accept cả &strString hay là i32Option không ?

Với IntoFrom chúng ta có thể perform conversion từ type X sang type Y. Cụ thể:

trait Into

Sẽ consumes self thành T

 trait Into<T> {
    fn into(self) -> T;
 }

Chú ý ở đây Self self ở đây có thể hiểu là this với các ngôn ngữ thông dùng như nodejs, php, ruby, .... Còn Self self là type của object.

Ví dụ:

fn into_vec<T: Into<Vec<u8>>>(t: T) {
println!("{:?}", t.into());
}
fn main() {
into_vec("hello world");
}
view raw playground.rs hosted with ❤ by GitHub

Output: [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]

Chúng ta đã truyền kiểu &str, nhưng nếu truyền kiểu String thì sẽ thế nào ?, fix lại chổ parameter

fn into_vec<T: Into<Vec<u8>>>(t: T) {
println!("{:?}", t.into());
}
fn main() {
into_vec("hello world".to_onwed());
}
view raw playground.rs hosted with ❤ by GitHub

hoặc

fn into_vec<T: Into<Vec<u8>>>(t: T) {
println!("{:?}", t.into());
}
fn main() {
into_vec("hello world".to_string());
}
view raw playground.rs hosted with ❤ by GitHub

Cả 2 hàm to_onwedto_string điều perform conversion từ &str sang String

Output: [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]

Chúng ta không cần care về việc parameter là kiểu gì chỉ cần quan tâm là kiểu của param đó có implments trait Into không. Tuy nhiên việc implements trait này tuyệt đối không khuyến khích, thay vào đó có cách khác là perform thông quan trait From.

trait From

Peform conversion từ type T sang Self

trait From<T> {
    fn from(T) -> Self;
}

Ví dụ:

string::from("world");

hoặc

String::from_utf8(vec![104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]);

Cả 2 ví dụ trên tuỳ thuộc vào type nhưng điều trả về String.

Quay trở lại trait Into, giữa IntoFrom có mối liên hệ nào không ?. Câu trả lời là có và rất là thân thiết như kiểu anh em với nhau vậy không thiếu một trong 2 được.

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

hay nhìn đơn giản thì

Into<U> for T nếu U: From<T>

Chúng ta implement Into thông qua From. Ví dụ có 2 struct A và B nếu muốn A: Into<B> thì phải có B: From<A>.

#[derive(Debug)]
struct A(i32);
#[derive(Debug)]
struct B(i32);
impl From<A> for B {
fn from(a: A) -> Self {
B(a.0)
}
}
fn into_b<T: Into<B>>(t: T) {
println!("{:?}", t.into());
}
fn main() {
let a = A(10);
into_b(a);
}
view raw playground.rs hosted with ❤ by GitHub

Output sẽ là B(10);

Lời kết

Với IntoFrom chúng ta đã trời lời được câu hỏi đầu bài, việc sử dụng IntoFrom rất đa dạng:

  • fn accept cả kiểu &str hoặc String
  • fn accept cả kiểu T hoặc Option<T>
    fn plus_5<T: Into<Option<i32>>>(t: T) {
    let x = t.into();
    println!("{:?}", x.unwrap() + 5);
    }
    fn main() {
    plus_5(Some(10));
    // plus_5(10);
    }
    view raw playground.rs hosted with ❤ by GitHub
  • fn accept cả kiểu [T] hoặc Vec<T>
  • ...
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
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 hơn 1 năm trước
0 0
{{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á!