返回保守的impl特征时,生命周期意味着什么?

时间:2018-05-15 13:44:59

标签: generics rust lifetime

在搜索有关保守impl trait 的文档时,I found this example

struct A {
    x: [(u32, u32); 10]
}

impl A {
    fn iter_values<'a>(&'a self) -> impl 'a + Iterator<Item = u32> {
        self.x.iter().map(|a| a.0)
    }
}

生命周期'a在返回类型中的含义是什么?

我知道this question about lifetime bound in Box,但我认为用例是不同的。如果我理解答案:

  

特质对象仅对生命周期'a

有效

这意味着生活在堆中某处的特征对象将在一生中持续'a

但是在这里,这不是一个特质对象,而是一个生活在堆栈中的具体对象。因此编译器不需要提供有关其生命周期的提示。

我对此缺少什么?

2 个答案:

答案 0 :(得分:11)

语法updateUser(user): Observable<object> { var putUrl = this.userURL + "/" + user.id; var result = this.http.put(putUrl, user).pipe( catchError(this.handleError) ); return result;} private handleError(error: HttpErrorResponse) { if (error.error instanceof ErrorEvent) { // A client-side or network error occurred. Handle it accordingly. console.error('An error occurred:', error.error.message); } else { // The backend returned an unsuccessful response code. // The response body may contain clues as to what went wrong, console.error( `Backend returned code ${error.status}, ` + `body was: ${error.error}`); } // return an observable with a user-facing error message return _throw( 'Something bad happened; please try again later.'); }; 表示

  • 函数定义的某些类型将被返回,但您不知道确切的类型。这是impl Iterator<Item = u32> + 'a部分。
  • 未指定的具体类型将是impl ...值的迭代器。这是u32部分。
  • 未指定的具体类型可能包含带有生命周期Iterator<Item = u32>的引用。这是'a部分。

在您的示例中,返回的迭代器包含对+ 'a的引用,因此不能允许它比self的实例更长寿,否则它将无效。具体类型(如果我们可以写的那样)将是A - 请注意它中有一个iter::Map<slice::Iter<'a, (u32, u32)>, <closure>>

  

这意味着生活在堆中某处的特征对象将在一生中持续'a

这不是真的。两种情况都具有相同的含义:未指定的具体类型可能包含引用。对于特征对象,具体类型位于某种指针('aBox&等)后面。使用impl trait,具体类型直接放在堆栈上。

  

这不是特质对象,而是存在于堆栈中的具体对象

Trait对象不需要堆;他们只能利用堆栈:

Rc

另见:

答案 1 :(得分:3)

  

这意味着生活在堆中某处的特征对象将在一生中持续'a

不完全。

'a这里没有完全指定,它只在对象的生命周期中放置一个上限。无论对象位于堆上还是堆栈上都无关紧要:编译器必须确保此对象的生命周期不超过'a

生命周期代表被引用和引用之间的关系,用于确保指示对象永远不会超过被引用的对象。因此,它在所指对象的生命周期中设置了上限,并且在所引用的生命周期中设置了下限。

编译器可以从函数返回的实际具体类型中获取必要的生命周期,但是它需要类型检查器能够查看函数实现来执行其工作

在接口边界记录生命周期约束对人类和编译器都更友好:它允许本地推理。