前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Rust日报】2020-08-07 无船同志关于Rust未来Generator语法的新尝试

【Rust日报】2020-08-07 无船同志关于Rust未来Generator语法的新尝试

作者头像
MikeLoveRust
发布2020-08-11 10:47:06
5690
发布2020-08-11 10:47:06
举报
文章被收录于专栏:Rust语言学习交流

Propane: an experimental generator syntax for Rust

众所周知,Rust的Generator一直没有稳定,主要原因是Generator仍然有许多设计上的问题没有明确,所以无船同志写了一个名字叫Propane的新crate,旨在nightly上实验性的探索Rust Generator未来语法的可能性。

Propane中文翻译:丙烷,无船同志取名向来看起来比较奇怪,不知道是否有其他用意

目前nightly的generator只能写成闭包的形式(官方称作generator literal),比如这样:

代码语言:javascript
复制
#![feature(generators, generator_trait)]

fn main() {
    let mut generator = || {
        yield 1;
        return "foo"
    };
}

如果你写成这样的话:

代码语言:javascript
复制
#![feature(generators, generator_trait)]

fn fake_generator() -> &'static str {
    yield 1;
    return "foo"
}

fn main() {
    let mut generator = fake_generator;
}

编译器会报E0627 A yield expression was used outside of the generator literal.这个错。也就是目前的generator不支持以函数的方式写。

前面说了,generator很多语法没有稳定甚至不支持,主要原因还是很多设计理念没有明确,所以Propane这个库先迈出了第一步。

代码语言:javascript
复制
#![feature(generators, generator_trait, try_trait)]

#[propane::generator]
fn fizz_buzz() -> String {
   for x in 1..101 {
      match (x % 3 == 0, x % 5 == 0) {
          (true, true)  => yield String::from("FizzBuzz"),
          (true, false) => yield String::from("Fizz"),
          (false, true) => yield String::from("Buzz"),
          (..)          => yield x.to_string(),
      }
   }
}

fn main() {
    let mut fizz_buzz = fizz_buzz();
    assert_eq!(&fizz_buzz.next().unwrap()[..], "1");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "2");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Fizz");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "4");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Buzz");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Fizz");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "7");

    // yada yada yada
    let mut fizz_buzz = fizz_buzz.skip(90);

    assert_eq!(&fizz_buzz.next().unwrap()[..], "98");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Fizz");
    assert_eq!(&fizz_buzz.next().unwrap()[..], "Buzz");
    assert!(fizz_buzz.next().is_none());
}

Propane提供了一个generator宏,可以让我们以函数的方式写Generator。当然Propane的主要目的是为了验证两个主要的设计理念是否合理:

1) 默认返回Iterator;return关键字可以终止generator,但只支持返回(); generator中的?表达式的默认行为和普通函数有差别

用Propane的generator宏标记的函数是一个返回impl Iterator的生成器,生成器中依然可以使用return关键字来终止,但是不能返回其他类型的值,只支持返回()

生成器中支持?表达式,但是与普通函数中不同的是,如果生成器yield是一个Result类型,当?表达式碰到错误情况时会把错误yield出去,而不是return出去。然后在下一次resume直接退出生成器。

2) 不支持自引用(Self-referential)

async/await语法稳定的时候为了解决自引用的问题花了很大的心思设计Pin和Unpin等概念。如果Generator默认返回迭代器Iterator的话,我们依然会碰到了自引用的问题。因为Iterator::next在1.0就稳定了,我们不可能再去修改它的API来让迭代器支持自引用。如果不考虑性能,目前最简单粗暴的方法是可以把Generator的每个state装箱到堆上。

当然如果我们不支持自引用,就可以让generator支持零开销(zero cost),而且无船同志也大胆的推测(hypothesis):也许我们确实不需要一个支持自引用的Generator。

最后,无船同志强调,这几个理念仅仅是实验性的,而且也有可能是一次失败的尝试。

以上是我了解完Propane之后结合无船的博客整理的文章,Propane的代码也很简洁,大家可以去Github查看。

来源我的博客文章:https://folyd.com/blog/rust-generator-experimental/

无船的博客文章:Propane: an experimental generator syntax for Rust

Rust GameDev 月报#12 - July 2020

链接:https://rust-gamedev.github.io/posts/newsletter-012

MeiliSearch 0.13版

MeiliSearch 是Rust写的一个类似 Algolia Search 的开源版搜索引擎。

链接:https://blog.meilisearch.com/whats-new-in-0-13-0/

Building Canrun: A statically typed logic programming library for Rust (part 1)

作者在用Rust写一个名叫Canrun的逻辑编程(logic programming)库,这是他这是这一系列连载博客的第一篇。

链接: https://esimmler.com/building-canrun-part-1/

Parallel stream processing with Rayon

作者写了一遍博客分享他使用Rayon的并发流式处理体验。

链接:https://morestina.net/blog/1432/parallel-stream-processing-with-rayon

-- From 日报小组 Folyd

社区学习交流平台订阅:

  • Rustcc论坛: 支持rss
  • 微信公众号:Rust语言中文社区
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rust语言学习交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Propane: an experimental generator syntax for Rust
    • 1) 默认返回Iterator;return关键字可以终止generator,但只支持返回(); generator中的?表达式的默认行为和普通函数有差别
      • 2) 不支持自引用(Self-referential)
      • Rust GameDev 月报#12 - July 2020
      • MeiliSearch 0.13版
      • Building Canrun: A statically typed logic programming library for Rust (part 1)
      • Parallel stream processing with Rayon
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档