为类型实参表示确切的生存期(较高约束)

问题描述 投票:3回答:1

据我所知,在Rust中,T: 'a表示“任何提供的类型参数T的所有生存期都必须超过'a”。

pub struct A<'a, T: 'a> {
    field: &'a T
}

这是大多数情况下自然想要的。


我偶然发现了一种情况,我需要表达“任何提供的类型参数T的所有生存期必须准确 'a”(即,既不过期也不被'a终止)。

pub struct A<'a, T<'a>> {  // imaginary syntax
    field: &'a T
}

有没有一种表达方式?


[请注意,我可以通过为单个T编写专门的代码来轻松实现此目的,因为这样一来,我可以为'a的任何给定值指定确切的寿命T

pub struct AForB<'a> {
    field: &'a B<'a>
}

pub struct B<'a> {
    other: &'a str
}

pub struct AForC<'a> {
    field: &'a C<'a>
}

pub struct C<'a> {
    other: &'a i32
}

但是对于泛型,Rust似乎只允许我将其表示为“生存期”关系(至少使用我知道的任何语法),这等效于已编写:

pub struct AForB<'a, 'b: 'a> {
    field: &'a B<'b>
}

pub struct B<'a> {
    other: &'a str
}

pub struct AForC<'a, 'b: 'a> {
    field: &'a C<'b>
}

pub struct C<'a> {
    other: &'a i32
}

以上内容当然可以编译,但是在我的情况下是不正确的。从某种意义上说,“不正确”与所使用的数据存储的语义不匹配,因此在这些定义下,借用检查器将接受不正确的代码。

rust borrow-checker
1个回答
0
投票

要使结构在T上协变而在'a上不变,您会这样做:

use std::marker::PhantomData;
use std::cell::Cell;

struct A<'a, T: 'a> {
    field: &'a T,
    _phantom: PhantomData<Cell<&'a ()>>
}

fn test_invariance<'a, T>(a: A<'static, T>) -> A<'a, T> {
    a // compiler error, A is invariant over 'a, can't coerce 'static into 'a
}

playground

进一步阅读:

© www.soinside.com 2019 - 2024. All rights reserved.