相关疑难解决方法(0)

无法推断返回引用的闭包的适当生命周期

考虑以下代码:

fn foo<'a, T: 'a>(t: T) -> Box<Fn() -> &'a T + 'a> {
    Box::new(move || &t)
}
Run Code Online (Sandbox Code Playgroud)

我期待的是:

  • T型具有寿命'a.
  • 这个价值t只要有效T.
  • t 移动到关闭,所以关闭生活只要 t
  • 闭包返回一个引用t移动到闭包的引用.因此只要闭包存在,引用就是有效的.
  • 没有生命周期问题,代码编译.

实际发生了什么:

  • 代码无法编译:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
 --> src/lib.rs:2:22
  |
2 |     Box::new(move || &t)
  |                      ^^
  |
note: first, the lifetime cannot outlive the lifetime  as defined on the body at 2:14...
 --> src/lib.rs:2:14
  |
2 | …
Run Code Online (Sandbox Code Playgroud)

closures ownership rust borrowing

16
推荐指数
2
解决办法
967
查看次数

迭代器通过引用返回项目,终身问题

我有一个终身问题,我正在尝试实现一个迭代器,通过引用返回它的项目,这里是代码:

struct Foo {
   d: [u8; 42],
   pos: usize
}

impl<'a> Iterator<&'a u8> for Foo {
   fn next<'a>(&'a mut self) -> Option<&'a u8> {
      let r = self.d.get(self.pos);
      if r.is_some() {
         self.pos += 1;
      }
      r
   }
}

fn main() {
   let mut x = Foo {
      d: [1; 42],
      pos: 0
   };

   for i in x {
      println!("{}", i);
   }
}
Run Code Online (Sandbox Code Playgroud)

但是这段代码编译不正确,我得到一个与参数生命周期有关的问题,这里是相应的错误:

$ rustc test.rs
test.rs:8:5: 14:6 error: method `next` has an incompatible type for trait: expected …
Run Code Online (Sandbox Code Playgroud)

iterator reference lifetime rust

12
推荐指数
1
解决办法
1557
查看次数

可变地迭代 &amp;[1,2,3,4,5,6,7,8,9] 以接收 `&amp;mut [1,4,7]` 然后 `&amp;mut [2,5,8]` 然后 `&amp;mut[ 3,6,9]`

我试图迭代分成块的切片,并返回一个包含每个块的第 n 个元素的元组。

例子:

&[1,2,3,4,5,6,7,8,9]

我想将其分成大小为 3 的块,然后迭代结果,返回这些元组,每个 next() 调用返回一个元组:

&mut[1,4,7], &mut[2,5,8], &mut[3,6,9]

我知道对于一般的东西,不可能返回可变的东西,这显然是不相交的,并且没有不安全的代码,我们可以拥有ChunksMuthttps://doc.rust-lang.org/std/slice/struct.ChunksMut .html)迭代器,所以也许有办法!。例如,我可以有 3 个ChunksMut,然后编译器知道从它们返回的元素是不相交的。

这是我对非可变的尝试:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cfa7ca0bacbe6f1535050cd7dd5c537c

PS:我想避免每次迭代时使用 Vec 或任何分配

rust

6
推荐指数
1
解决办法
1069
查看次数

如何在结构字段上创建可变迭代器

所以我正在使用 Rust 开发一个小的 NES 模拟器,我正在尝试使用我的状态寄存器。寄存器是一个结构,其中包含一些包含布尔值的字段(标志),寄存器本身是 CPU 结构的一部分。现在,我想遍历这些字段并根据我执行的一些指令设置 bool 值。但是,我无法实现可变迭代器,我已经实现了一个 into_iter() 函数并且能够遍历字段以获取/打印 bool 值,但是如何在结构本身内改变这些值?这甚至可能吗?

pub struct StatusRegister {
    CarryFlag: bool,
    ZeroFlag: bool,
    OverflowFlag: bool,
}

impl StatusRegister {
    fn new() -> Self {
        StatusRegister {
            CarryFlag: true,
            ZeroFlag: false,
            OverflowFlag: true,
        }
    }
}

impl<'a> IntoIterator for &'a StatusRegister {
    type Item = bool;
    type IntoIter = StatusRegisterIterator<'a>;

    fn into_iter(self) -> Self::IntoIter {
        StatusRegisterIterator {
            status: self,
            index: 0,
        }
    }
}

pub struct StatusRegisterIterator<'a> {
    status: &'a StatusRegister,
    index: usize, …
Run Code Online (Sandbox Code Playgroud)

struct iterator reference mutable rust

3
推荐指数
1
解决办法
632
查看次数

提取迭代器链调用辅助函数

我正在尝试编写一个函数,它将封装一系列链接的迭代器方法调用(.lines().map(...).filter(...)),我目前已经重复了这些调用.我无法弄清楚要编译的类型签名.如果对于Rust来说这是不可能的或非常单一的,我会接受一种惯用法的建议.

use std::fs;
use std::io;
use std::io::prelude::*;
use std::iter;

const WORDS_PATH: &str = "/usr/share/dict/words";

fn is_short(word: &String) -> bool {
    word.len() < 7
}

fn unwrap(result: Result<String, io::Error>) -> String {
    result.unwrap()
}

fn main_works_but_code_dupe() {
    let file = fs::File::open(WORDS_PATH).unwrap();
    let reader = io::BufReader::new(&file);
    let count = reader.lines().map(unwrap).filter(is_short).count();
    println!("{:?}", count);

    let mut reader = io::BufReader::new(&file);
    reader.seek(io::SeekFrom::Start(0));
    let sample_size = (0.05 * count as f32) as usize; // 5% sample

    // This chain of iterator logic is duplicated
    for …
Run Code Online (Sandbox Code Playgroud)

iterator rust

2
推荐指数
1
解决办法
238
查看次数

从迭代器返回切片时无法推断出适当的生命周期

我有Vec<Point>一个简单的struct Point {x: f32, y: f32, z: f32}.我的矢量代表3D中数十万行(实际上可能是一行Vec<Vec<Point>>),因此我会跟踪所有行的开始/结束.

pub struct Streamlines {
    lengths: Vec<usize>,
    offsets: Vec<usize>,  // cumulative sum of lengths
    data: Vec<Point>,
}
Run Code Online (Sandbox Code Playgroud)

我想为它创建一个非消耗的迭代器,可用如下:

for streamline in &streamlines {
    for point in &streamline {
        println!("{} {} {}", point.x, point.y, point.z);
    }
    println!("")
}
Run Code Online (Sandbox Code Playgroud)

我找到了如何为一个简单的结构实现Iterator和IntoIterator?并开始copyi-err,适应:)

impl IntoIterator for Streamlines {
    type Item = &[Point];
    type IntoIter = StreamlinesIterator;

    fn into_iter(self) -> Self::IntoIter {
        StreamlinesIterator {
            streamlines: self,
            it_idx: 0
        } …
Run Code Online (Sandbox Code Playgroud)

rust

0
推荐指数
1
解决办法
155
查看次数