Quick implement iterator Rust
Rust
27
White

Giang Nguyen viết ngày 20/03/2017

Nếu chúng ta có API đơn giản như get response headers từ website amazon.com làm
sao chúng ta có thể dùng sugar systax giống như:

for key, value in response.headers {
  println!("({}, {})", key, value);
}

Để làm được việc đó đơn giản nhất ở Rust là bạn sẽ implement lại trait

std::iter::Iterator

Với required methods:

fn next(&mut self) -> Option<Self::Item> {}

Khai báo type Headers:

#[derive(Debug)]
struct Headers {
  idx: 0,
  contents: Vec<String>
}

Implement struct Headers:

impl Headers {
  fn new(contents: Vec<String>) -> Self {
    Headers {
      idx: 0,
      contents: contents
    }
  }
}

Implement trait Iterator:

impl Iterator for Headers {
    type Item = (String, String);
    fn next(&mut self) -> Option<Self::Item> {
        self.idx += 1;
        let len = self.contents.len();
        if self.idx >= len {
            return None;
        } else {
            if let Some(i) = self.contents[self.idx].find(":") {
                return Some((self.contents[self.idx][..i].to_string(),
                             self.contents[self.idx][i + 1..].trim().to_string()));
            } else {
                return Some((self.contents[self.idx].to_string(), "".to_string()));
            }
        }
    }
}

Test lại:

fn main() {
     let mut handle = Easy::new();
     let mut data = Vec::new();
     handle.url("https://www.amazon.com").unwrap();
     {
        let mut transfer = handle.transfer();
        transfer.header_function(|header| {
                data.push(str::from_utf8(header).unwrap().to_string());
                true
            })
            .unwrap();
        transfer.perform().unwrap();
     }

     let mut headers = Headers::new(data);
     println!("{:?}", headers.next());
     //Some(("Content-Type", "text/html"))
}

Update 1:

Implement trait IntoIterator và sửa lại struct Headers

#[derive(Debug)]
struct HeadersIterator {
    idx: usize,
    contents: Vec<String>,
}

#[derive(Debug)]
struct Headers {
    contents: Vec<String>,
}

impl Headers {
    fn new(contents: Vec<String>) -> Self {
        Headers { contents: contents }
    }
}

impl IntoIterator for Headers {
    type Item = (String, String);
    type IntoIter = HeadersIterator;

    fn into_iter(self) -> Self::IntoIter {
        HeadersIterator::new(self.contents)
    }
}

impl HeadersIterator {
    fn new(contents: Vec<String>) -> Self {
        HeadersIterator {
            idx: 0,
            contents: contents,
        }
    }
}

impl Iterator for HeadersIterator {
    type Item = (String, String);
    fn next(&mut self) -> Option<Self::Item> {
        self.idx += 1;
        let len = self.contents.len();
        if self.idx >= len {
            return None;
        } else {
            if let Some(i) = self.contents[self.idx].find(":") {
                return Some((self.contents[self.idx][..i].to_string(),
                             self.contents[self.idx][i + 1..].trim().to_string()));
            } else {
                return Some((self.contents[self.idx].to_string(), "".to_string()));
            }
        }
    }
}

fn main() {
    let mut handle = Easy::new();
    let mut data = Vec::new();
    handle.url("https://www.amazon.com").unwrap();
    {
        let mut transfer = handle.transfer();
        transfer.header_function(|header| {
                data.push(str::from_utf8(header).unwrap().to_string());
                true
            })
            .unwrap();
        transfer.perform().unwrap();
    }

    let headers = Headers::new(data);

    let mut iter = headers.into_iter();

    let test = iter.next();

    println!("{:?}", test);
  // Some(("Content-Type", "text/html"))
}

Link

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
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 10 tháng 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á!