【Rust日報】2019-09-14 – Rust Bay Area Meetup影片發布

  • 2019 年 10 月 4 日
  • 筆記

Rust Bay Area Meetup – 2019年9月12日

Meetup以對pcwalton :p的特寫開場,並包含了兩個內容:

  • Jane Lusby討論了他對rust的一些建議
  • Adam Perry與大家交流了rust的UI和Moxie框架

Meetup影片已上傳至YouTube。

用rust編寫的zstd解碼器

Zstandard演算法是一個無損壓縮數據的格式,該格式獨立於CPU類型、作業系統、文件系統和字符集,適用於文件壓縮、通道和流壓縮。 即使對於任意長的順序呈現的輸入數據流,也可以僅使用有限量的先驗中間存儲來產生或減少數據,因此可以用於數據通訊。該壓縮格式使用Zstandard壓縮方法並使用xxHash-64校驗方法(可選)來檢測數據損壞。 以Zstandard定義的數據格式不會允許隨機訪問壓縮數據。 兼容的解壓器必須能夠解壓縮至少一個符合此處提供的規範的工作參數集。它也可能會忽略例如校驗和之類的資訊欄位。只要它不支援壓縮流中定義的參數,它就必須產生一個非模糊的錯誤程式碼和相關的錯誤消息,說明那個參數不受支援。

目前此rust工程已經能夠做到:

  1. 解析/ decodecorpus_files中的所有文件。這些是由原始zstd開發人員使用decodecorpus生成的
  2. 將所有這些都正確解碼到輸出緩衝區
  3. 解碼我在本地創建的所有decode_corpus文件(1000+)

更多資訊可以前往GitHub上瀏覽。

對封裝trait對象或trait對象引用的集合進行操作

這裡有一個trait:

trait Get {      fn get(&self) -> u32;  }  

以及一些實現該trait的類型:

struct Foo(u32);  struct Bar(u16, u16, u16);    impl Get for Foo {      fn get(&self) -> u32 {          self.0      }  }    impl Get for Bar {      fn get(&self) -> u32 {          self.0 as u32 + self.1 as u32 + self.2 as u32      }  }  

這些特徵對象通常以兩種方式在集合中結尾:

let mut v1 = Vec::<&dyn Get>::new();     // collection of trait object references  let mut v2 = Vec::<Box<dyn Get>>::new(); // collection of boxed trait objects  

想要一個可以對這個特徵對象的泛型集合進行操作的函數,但將迭代器作為參數傳遞是否是一個正確的方法呢?

fn sum_from_iter_box<'a, I, T>(it: I)  where      I: IntoIterator<Item = &'a Box<T>>,    // <-- Box<T>      T: Get + 'a + ?Sized,  { ... }    fn sum_from_iter_ref<'a, I, T>(it: I)  where      I: IntoIterator<Item = &'a &'a T>,     // <-- &'a T      T: Get + 'a + ?Sized,  { ... }  

如何編寫一個可以使用I類型的Iterator的單個函數?有更好的方法嗎?

下列程式碼解決了上述問題,且未添加任何trait的實現。

use std::ops::Deref;    fn sum_from_iter<'a, I, T, U>(it: I)  where      I: IntoIterator<Item = &'a T>,      T: Deref<Target=U> + 'a,      U: Get + ?Sized,  {      let sum = it.into_iter().fold(0, |acc, get| get.deref().get() + acc);      println!("sum: {}", sum);  }    trait Get {      fn get(&self) -> u32;  }    struct Foo(u32);  struct Bar(u16, u16, u16);    impl Get for Foo {      fn get(&self) -> u32 {          self.0      }  }    impl Get for Bar {      fn get(&self) -> u32 {          self.0 as u32 + self.1 as u32 + self.2 as u32      }  }    fn main() {      let mut v1 = Vec::<&dyn Get>::new();      let aaa = &Foo(1234);      let bbb = &Foo(4321);      v1.push(aaa);      v1.push(bbb);      sum_from_iter(v1.iter());        let ccc = &Bar(1, 1, 1);      v1.push(ccc);      sum_from_iter(v1.iter());        let mut v2 = Vec::<Box<dyn Get>>::new();      v2.push(Box::new(Foo(123)));      v2.push(Box::new(Foo(321)));      sum_from_iter(v2.iter());        v2.push(Box::new(Bar(1, 1, 1)));      sum_from_iter(v2.iter());  }  

通常最好使用Get自動地為所有引用類型實現trail,這樣就不需要對其所有函數普遍操作。

Read More:Reddit原帖鏈接


From 日報小組 @Lance

日報訂閱地址:

獨立日報訂閱地址:

  • Telgram Channel
  • 阿里雲語雀訂閱
  • Steemit
  • GitHub

社區學習交流平台訂閱:

  • Rust.cc論壇: 支援rss
  • Rust Force: 支援rss
  • 微信公眾號:Rust語言學習交流