给定一个简单的异步函数:
async fn foo(n: usize) -> usize {
if n > 0 { foo(n - 1).await }
else { 0 }
}
编译器抱怨说< code>async fn必须重写才能返回装箱的< code>dyn Future。
| async fn foo(n: usize) -> usize {
| ^^^^^ recursive `async fn`
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
For more information about this error, try `rustc --explain E0733`.
编译器解释(rustc--在解释E0733
):
要实现异步递归,需要对异步 fn
进行解加,以便在返回类型中显式显示 Future
:
use std::future::Future;
fn foo_desugared(n: usize) -> impl Future<Output = ()> {
async move {
if n > 0 {
foo_desugared(n - 1).await;
}
}
}
最后,未来被包裹在一个钉着的盒子里:
use std::future::Future;
use std::pin::Pin;
fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
Box::pin(async move {
if n > 0 {
foo_recursive(n - 1).await;
}
})
}
盒子
现在考虑以下代码:
fn foo(n: &usize) -> Pin<Box<dyn Future<Output = usize>>> {
Box::pin(async move {
if *n > 0 {
foo(&n).await
} else {
0
}
})
}
编译器抱怨
| fn foo(n: &usize) -> Pin<Box<dyn Future<Output = usize>>> {
| ------ help: add explicit lifetime `'static` to the type of `n`: `&'static usize`
| / Box::pin(async move {
| | if *n > 0 {
| | foo(&n).await
| | } else {
| | 0
| | }
| | })
| |______^ lifetime `'static` required
请帮助我了解这是怎么回事。
默认情况下,Trait 对象 (dyn Trait
) 将具有静态生存期,除非另有指定。因此,没有指定生存期的盒装期货(和其他特征)不能依赖于借用的数据,除非在“静态
生存期”中借用了该数据。(这是您的错误消息所抱怨的)。
要解决此问题,您可以显式指定生存期,也可以只使用“_
,在这种情况下,它将使用n的省略生存期:
// .-- will use elided lifetime from here
// v v-- give the future a non-'static lifetime
fn foo(n: &usize) -> Pin<Box<dyn '_ + Future<Output = usize>>> {
// or: fn foo<'a>(n: &'a usize) -> Pin<Box<dyn 'a + Future<Output = usize>>>
Box::pin(async move {
if *n > 0 {
foo(&n).await // <-- no error, as the future lifetime now depends on the
// lifetime of n instead of having a 'static lifetime
} else {
0
}
})
}
谁能告诉我为什么函数参数不能是?这是函数参数在上声明并在函数返回时被取消分配的原因吗?没有办法保留参数值?只是糊涂了。请澄清。 多谢了。
问题内容: 我有一个异步函数,要连续多次调用。问题是“多个”可以是几十万或数百万… 显而易见的方法是从回调中调用相同的函数,如下所示: 当然,涉及一些逻辑来停止递归。问题是堆栈是否充满了调用,并可能在某些时候导致堆栈溢出? 问题答案: 问题是堆栈是否充满了调用,并可能在某些时候导致堆栈溢出? 否。 如果调用回调是异步传递的,则不会堆积堆栈。 在您的代码中: 这是逐步发生的事情: 首先被称为。 然后
问题内容: 必须使用无参数构造函数(像Hibernate这样的工具会在此构造函数上使用反射来实例化对象)。 我得到了这个手挥手的答案,但是有人可以进一步解释吗?谢谢 问题答案: hibernate,并且通常通过反射创建对象的代码用于创建类的新实例。此方法需要一个公共的无参数构造函数才能实例化该对象。对于大多数用例,提供无参数构造函数不是问题。 有一些基于序列化的技巧可以解决没有no-arg构造函数
在§13.3.1/4(N3337)中,您会发现以下内容: 对于静态成员函数,隐式对象参数被认为与任何对象匹配(因为如果选择了函数,则丢弃对象)。 §9.4.1/2有这样一种说法: 静态成员函数没有this指针。 那么,静态成员函数的隐式对象参数的用途是什么?
问题内容: 我在课堂上有这个功能: 我尝试使用此函数来调用该函数: 问题是编译器希望它看起来像这样: 为什么第一个会导致错误? 问题答案: Swift 2.0更新 :现在,默认情况下,函数的功能与方法相同,并且对于两种方法而言: 第一个参数没有外部名称;和 其他参数的外部名称与内部名称相同。 除此之外,下面的规则仍然适用,只是速记语法已消失。 这是一个更一般的答案:函数在类之外定义为真函数时以及在
我正在阅读有关java中的同步概念的信息,并遇到了同步语句。 我想知道,为什么我们向它传递参数,尽管它看起来像静态块(这只是一个例子),并且传递的参数没有指定任何数据类型。 例: 如果有人知道,请解释。