标签: lifetime

如何使用返回可变引用的迭代器创建自己的数据结构?

我在Rust中创建了一个数据结构,我想为它创建迭代器.不可变的迭代器很容易.我目前有这个,它工作正常:

// This is a mock of the "real" EdgeIndexes class as
// the one in my real program is somewhat complex, but
// of identical type

struct EdgeIndexes;

impl Iterator for EdgeIndexes {
    type Item = usize;
    fn next(&mut self) -> Option<Self::Item> {
        Some(0)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

pub struct CGraph<E> {
    nodes: usize,
    edges: Vec<E>,
}

pub struct Edges<'a, E: 'a> {
    index: EdgeIndexes,
    graph: &'a CGraph<E>,
}

impl<'a, E> Iterator …
Run Code Online (Sandbox Code Playgroud)

lifetime rust

28
推荐指数
1
解决办法
4447
查看次数

如何在关联类型中指定生命周期参数?

我有这个特点和简单的结构:

use std::path::{Path, PathBuf};

trait Foo {
    type Item: AsRef<Path>;
    type Iter: Iterator<Item = Self::Item>;

    fn get(&self) -> Self::Iter;
}

struct Bar {
    v: Vec<PathBuf>,
}
Run Code Online (Sandbox Code Playgroud)

我想实现以下Foo特征Bar:

impl Foo for Bar {
    type Item = PathBuf;
    type Iter = std::slice::Iter<PathBuf>;

    fn get(&self) -> Self::Iter {
        self.v.iter()
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我收到了这个错误:

error[E0106]: missing lifetime specifier
  --> src/main.rs:16:17
   |
16 |     type Iter = std::slice::Iter<PathBuf>;
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ expected lifetime parameter
Run Code Online (Sandbox Code Playgroud)

我发现无法在相关类型中指定生命周期.特别是我想表达迭代器不能超过self生命周期.

我如何修改Foo特征或Bar特征实现来使其工作?

铁锈操场

lifetime rust

27
推荐指数
2
解决办法
5210
查看次数

函数返回的字符串文字的生命周期

考虑以下代码:

const char* someFun() {
    // ... some stuff
    return "Some text!!"
}

int main()
{
   { // Block: A
      const char* retStr = someFun();
      // use retStr
   }
}
Run Code Online (Sandbox Code Playgroud)

在函数中someFun(),"Some text!!"存储的位置(我认为它可能在ROM的某个静态区域)以及它是什么范围 一生?

指向的内存是否会在retStr整个程序中被占用,或者在块A退出后被释放?

c c++ lifetime string-literals

25
推荐指数
3
解决办法
5435
查看次数

std :: initializer_list返回值的生命周期

GCC的实现破坏了std::initializer_list返回full-expression结束时从函数返回的数组.它是否正确?

此程序中的两个测试用例都显示在使用值之前执行的析构函数:

#include <initializer_list>
#include <iostream>

struct noisydt {
    ~noisydt() { std::cout << "destroyed\n"; }
};

void receive( std::initializer_list< noisydt > il ) {
    std::cout << "received\n";
}

std::initializer_list< noisydt > send() {
    return { {}, {}, {} };
}

int main() {
    receive( send() );
    std::initializer_list< noisydt > && il = send();
    receive( il );
}
Run Code Online (Sandbox Code Playgroud)

我认为该计划应该有效.但潜在的标准有点令人费解.

return语句初始化一个返回值对象,就像它被声明一样

std::initializer_list< noisydt > ret = { {},{},{} };
Run Code Online (Sandbox Code Playgroud)

initializer_list将从给定的初始化器系列初始化一个临时及其底层数组存储,然后initializer_list从第一个初始化器初始化另一个.阵列的寿命是多少?"数组的生命周期与initializer_list对象的生命周期相同." 但其中有两个; 哪一个是模棱两可的.8.5.4/6中的示例(如果它按照公布的方式工作)应该解决数组具有复制到对象的生命周期的歧义.然后返回值的数组也应该存在于调用函数中,并且应该可以通过将它绑定到命名引用来保留它.

LWS上 …

c++ lifetime initializer-list c++11 list-initialization

25
推荐指数
2
解决办法
4610
查看次数

在Rust中使用struct的生命周期的正确方法是什么?

我想写这个结构:

struct A {
    b: B,
    c: C,
}

struct B {
    c: &C,
}

struct C;
Run Code Online (Sandbox Code Playgroud)

B.c应借A.c.

A ->
  b: B ->
    c: &C -- borrow from --+
                           |
  c: C  <------------------+
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的:struct C;

struct B<'b> {
    c: &'b C,
}

struct A<'a> {
    b: B<'a>,
    c: C,
}

impl<'a> A<'a> {
    fn new<'b>() -> A<'b> {
        let c = C;
        A {
            c: c,
            b: B { c: &c },
        }
    }
}

fn …
Run Code Online (Sandbox Code Playgroud)

lifetime rust

25
推荐指数
2
解决办法
2万
查看次数

如何设置会话的生命周期

如何在PHP中设置会话生存期?只要请求存在,我想将其设置为永久.请求是AJAX.我处理AJAX请求的PHP代码是:

// AJAX.php
<?php    
session_start();

$_SESSION['counter'] = $_SESSION['counter'] + 1;

header('Content-type: application/json');    
echo json_encode(array('tick' => $_SESSION['counter']));
?>
Run Code Online (Sandbox Code Playgroud)

和JavaScript:

$(document).ready(function() {            
function check() {
    getJSON('ajax.php');        
}

function getJSON(url) {                                
    return $.getJSON(
                url,
                function(data) {
                    $("#ticker").html(data.tick);
                }
           );
}

setInterval(function() {
    check();
}, 10000); // Tick every 10 seconds

});
Run Code Online (Sandbox Code Playgroud)

会话总是在300秒后重置.

php session lifetime

24
推荐指数
4
解决办法
9万
查看次数

如何编写一个返回对自身引用的迭代器?

我无法表达Iterator实现的返回值的生命周期.如何在不更改迭代器的返回值的情况下编译此代码?我希望它返回一个引用的向量.

很明显,我没有正确使用生命周期参数,但在尝试了我放弃的各种方法之后,我不知道如何处理它.

use std::iter::Iterator;

struct PermutationIterator<T> {
    vs: Vec<Vec<T>>,
    is: Vec<usize>,
}

impl<T> PermutationIterator<T> {
    fn new() -> PermutationIterator<T> {
        PermutationIterator {
            vs: vec![],
            is: vec![],
        }
    }

    fn add(&mut self, v: Vec<T>) {
        self.vs.push(v);
        self.is.push(0);
    }
}

impl<T> Iterator for PermutationIterator<T> {
    type Item = Vec<&'a T>;
    fn next(&mut self) -> Option<Vec<&T>> {
        'outer: loop {
            for i in 0..self.vs.len() {
                if self.is[i] >= self.vs[i].len() {
                    if i == 0 {
                        return None; // we are done …
Run Code Online (Sandbox Code Playgroud)

iterator lifetime rust

24
推荐指数
3
解决办法
9208
查看次数

为什么需要绑定`T:'a`来存储引用`&'a T`?

鉴于此代码:

struct RefWrapper<'a, T> {
    r: &'a T,
}
Run Code Online (Sandbox Code Playgroud)

...编译器抱怨:

错误:参数类型T可能活不够长

考虑添加显式生命周期绑定,T: 'a以便引用类型&'a T不会超过它指向的数据.

我已经多次看过这个错误了,到目前为止我只是听了编译器,一切都很顺利.但是,考虑更多,我不明白为什么我要写T: 'a.

据我了解,已经不可能得到这样的参考.有&'a T暗示有类型的对象T是至少生存'a.但是我们不能在所述对象中存储任何引用,这些引用指向具有比生命周期短的数据'a.这已经导致编译错误.

在这个意义上它已经是不可能得到一个&'a T地方T不活得长'a.因此,附加注释(T: 'a)不应该是必需的.

我对吗?我错了,如果是的话:如果T: 'a不需要,我怎么能破坏代码呢?


链接:

lifetime rust

24
推荐指数
2
解决办法
437
查看次数

这个实例如何看似比自己的参数生命周期更长?

在我偶然发现下面的代码之前,我确信类型的生命周期参数中的生命周期总是比其自己的实例更长.换句话说,给定一个foo: Foo<'a>,那么'a总是会活得更久foo.然后我被@Luc Danton(游乐场)介绍给这个反辩论代码:

#[derive(Debug)]
struct Foo<'a>(std::marker::PhantomData<fn(&'a ())>);

fn hint<'a, Arg>(_: &'a Arg) -> Foo<'a> {
    Foo(std::marker::PhantomData)
}

fn check<'a>(_: &Foo<'a>, _: &'a ()) {}

fn main() {
    let outlived = ();
    let foo;

    {
        let shortlived = ();
        foo = hint(&shortlived);
        // error: `shortlived` does not live long enough
        //check(&foo, &shortlived);
    }

    check(&foo, &outlived);
}
Run Code Online (Sandbox Code Playgroud)

尽管foo创建者hint似乎认为生命周期与其自身一样长,并且对它的引用被传递给更广泛范围内的函数,但代码完全按原样编译.取消注释代码中声明的行会触发编译错误.或者,更改Foo为struct tuple (PhantomData<&'a ()>)也会使代码不再使用相同类型的错误进行编译(Playground).

如何有效的Rust代码?这里编译器的原因是什么?

lifetime rust

23
推荐指数
2
解决办法
1906
查看次数

在自己的初始化程序中使用变量

C++20 标准草案的[basic.scope.pdecl]/1在注释中包含以下(非规范性)示例(合并拉取请求 3580之前的部分引用,请参阅此问题的答案):

unsigned char x = x;
Run Code Online (Sandbox Code Playgroud)

[...] x 用它自己的(不确定的)值初始化。

这实际上在 C++20 中有明确定义的行为吗?


通常T x = x;,由于x的值在初始化完成之前是不确定的,因此表单的自初始化具有未定义的行为。评估不确定的值通常会导致未定义的行为([basic.indent]/2),但在[basic.indent]/2.3中有一个特定的例外,它允许直接unsigned charunsigned char具有不确定值的左值初始化变量(导致使用不确定值初始化)。

这本身并不会因此导致不确定的行为,但会为其他类型T不属于无符号窄字符类型或std::byteint x = x;。这些注意事项也适用于 C++17 及之前的版本,另请参阅底部的链接问题。

然而,即使对于unsigned char x = x;,当前草案的[basic.lifetime]/7说:

类似地,在对象的生命周期开始之前 [...] 使用不依赖于其值的泛左值的属性是明确定义的。在以下情况下,程序具有未定义的行为:

  • 泛左值用于访问对象,或

  • [...]

这似乎意味着x示例中的that值只能在其生命周期内使用。

[basic.lifetime]/1说:

[...]

类型 T 的对象的生命周期在以下情况下开始:

  • [...] 和
  • 它的初始化(如果有)完成(包括空初始化)([dcl.init]),

[...]

因此x的生命周期仅在初始化完成后才开始。但是在引用的例子中 …

c++ initialization lifetime language-lawyer c++20

23
推荐指数
1
解决办法
637
查看次数