如何参考通用返回值中关闭的类型?
我有一个包含一个函数的结构,可以说 f:fn() - >字符串
。我想在其构造函数中将其初始化为特定的默认函数,稍后可以将其覆盖,如果他们愿意的话。
struct Builder<F> {
func: F,
}
fn new_builder() -> ??? {
let hello = "hello".to_owned();
Builder { func: move || hello }
}
impl<F: Fn() -> String> Builder<F> {
fn build(self) -> String {
(self.func)()
}
}
但是如何编写 new_builder()
的返回类型,因为 || {}
有匿名类型吗?我尝试了 - &gt; Builder&lt; _&gt;
但失败(游乐场),并提出了一个甚至在语法上都不有效的解决方案:
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> src/lib.rs:5:29
|
5 | fn new_builder() -> Builder<_> {
| --------^-
| | |
| | not allowed in type signatures
| help: replace with the correct return type: `Builder<[closure@src/lib.rs:6:21: 6:26]>`
For more information about this error, try `rustc --explain E0121`.
我知道我可以通过制作 builder
带有一些拳击:
struct Builder {
func: Box<dyn Fn() -> ()>,
}
但是,这会在中间遇到额外的运行时 开销。分配和间接形式的形式,可能会使编译器更难优化,例如,直列调用 func
。在我的实际情况下,这种解决方法非常快,但是我仍然想知道Rust是否可以在这里坚持使用纯粹的静态解决方案。
有没有办法在不诉诸参考或拳击的情况下进行这项工作?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里的主要问题是闭合的类型无法用代码< /a>。
幸运的是,正是由于这个原因,
impl
return类型存在关键字:这意味着:“这是编译器会发现的一些未指定类型。这种类型实现
fnonce( ) - &gt; string
“。然后,使用
new_builder
的其他功能将能够访问func
作为fnonce() - &gt;字符串
对象。另请注意,我必须将类型更改为
fnonce
,因为func
在您的情况下会消耗hello
,因此仅一次可呼应一次。不用担心。
impl&lt; f:fnonce() - &gt;字符串&gt;
还包括fn
和fnmut
,因为它们也被隐含了fnonce
。The main problem here is that the type of a closure cannot be written out in code.
Luckily, for exactly that reason, the
impl
keyword exists for return types:Which means: "This is some unspecified type that the compiler will figure out. It's just important that this type implements
FnOnce() -> String
".Other functions that use
new_builder
will then be able to accessfunc
as anFnOnce() -> String
object.Also note that I had to change the type to
FnOnce
becausefunc
in your case consumes thehello
and is therefore only callable once.Don't worry, though.
impl<F: FnOnce() -> String>
also includesFn
andFnMut
, as they are alsoFnOnce
implicitely.