< 返回版块

LacneQin 发表于 2019-09-14 22:05

Tags:rust

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

日报订阅地址:

独立日报订阅地址:

社区学习交流平台订阅:

评论区

写评论

还没有评论

1 共 0 条评论, 1 页