递归函数类型

时间:2015-01-11 11:23:11

标签: rust

在Go中的词法扫描的Rob Pike's talk中,他定义了一个函数类型stateFn,它返回另一个stateFn,如下所示:

type stateFn func() stateFn

为了尝试在Rust中做类似的事情,我尝试了这个:

type stateFn = fn() -> stateFn;

但是编译器抱怨“非法递归类型;如果需要,可以在循环中插入枚举或结构”。

我可以在Rust中执行此操作,如果是,请执行此操作?

1 个答案:

答案 0 :(得分:15)

您可以将函数类型包装为名义类型(即结构或枚举)。这实际上是Go代码正在做的事情:type T U定义了一个新的,不同的类型T,它不能与U直接互换,而Rust' {{1} }只是一个别名,如Haskell中的type和C中的type

所以,有人可能写道:

typedef

struct StateFn(fn() -> Option<StateFn>);

(我必须添加struct StateFn { f: fn() -> Option<StateFn> } ,因为Go的Option可以为nil,而Rust默认删除可空性,使其选择加入。)

那就是说,我怀疑func是Go中的闭包(可以存储一些内部状态),而Rust中的func只是一个函数指针(根本没有状态),所以你可以我也希望在Rust中使用一个封口。可以通过将fn替换为fn() -> Option<StateFn>并使用Box<Fn() -> Option<StateFn>>创建它来实现此目的。

也可以使用FnMut代替Box::new(move || { /* code here */ }),这样可以提供更大的灵活性,甚至FnOnce代表一个只能调用一次的闭包。这些中的每一个都对呼叫者有了更多的限制,但是给予封闭本身更多的灵活性。 (但是,&#34;对象安全&#34;关注意味着Fn目前无法正常工作,"Purging proc"有更多详细信息和解决方法。)

Box<FnOnce>

任何这些情况的解析循环可能如下所示:

struct StateFn {
    f: Box<FnMut() -> Option<StateFn>>
}