在Rob Pike谈到 Go中的词法扫描时,他定义了一个stateFn返回另一个的函数类型stateFn,如下所示:
type stateFn func() stateFn
Run Code Online (Sandbox Code Playgroud)
为了尝试在Rust中做类似的事情,我尝试了这个:
type stateFn = fn() -> stateFn;
Run Code Online (Sandbox Code Playgroud)
但编译器抱怨"非法递归类型;如果需要,在循环中插入枚举或结构".
我可以在Rust中执行此操作,如果是这样,怎么做?
huo*_*uon 15
您可以将函数类型包装为名义类型(即结构或枚举).这实际上是Go代码正在做的事情:type T U定义一个T不能直接互换的新的,不同的类型U,而Rust type只是一个别名,就像type在Haskell和typedefC中一样.
所以,有人可能写道:
struct StateFn(fn() -> Option<StateFn>);
Run Code Online (Sandbox Code Playgroud)
要么
struct StateFn {
f: fn() -> Option<StateFn>
}
Run Code Online (Sandbox Code Playgroud)
(我必须添加,Option因为Go func可以是nil,而Rust默认删除可空性,使其选择加入.)
也就是说,我怀疑这func是Go中的一个闭包(可以存储一些内部状态),而fn在Rust中只是一个函数指针(根本没有状态),所以你可能也想在Rust中使用一个闭包.有人可能会通过替换fn() -> Option<StateFn>a 并使用它来创建它.Box<Fn() -> Option<StateFn>>Box::new(move || { /* code here */ })
人们也可以使用FnMut而不是使用Fn它给你更多的灵活性,或者甚至FnOnce代表一个只能被调用一次的闭包.这些中的每一个都对呼叫者有了更多的限制,但是给予封闭本身更多的灵活性.(但是,"对象安全"问题意味着Box<FnOnce>此刻不起作用,"清除过程"有更多细节和解决方法.)
struct StateFn {
f: Box<FnMut() -> Option<StateFn>>
}
Run Code Online (Sandbox Code Playgroud)
任何这些情况的解析循环可能如下所示:
let mut state_fn = Some(initial_fn);
while let Some(mut f) = state_fn {
state_fn = (*f.f)()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1915 次 |
| 最近记录: |