小编Cha*_*man的帖子

如何创建一个大小有限的VecDeque?

我想实现一个VecDeque具有最大大小限制的。我有两个策略,但我都无法完成。

第一种方法:组合继承。

我创建了一个新结构:

pub struct LimVecDeque<T> {                                                                                                    
     deque: VecDeque<T>,                                                 
     limit: usize,                                                       
}

Run Code Online (Sandbox Code Playgroud)

并创建一个新的推送函数:

impl<T> LimVecDeque<T> {
  ...

  pub fn push (&self, elem: T) {
    self.deque.push_back(elem);
    if self.limit < self.deque.len() {
      self.deque.pop_front();
    }
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

这是可行的,但是随着我的程序的成长,我需要向我的LimVecDeque结构添加功能。其中大部分是原件的副本VecDeque

pub fn len(&self) -> usize {
  self.deque.len()
}
Run Code Online (Sandbox Code Playgroud)

我还有更多问题需要导出VecDeque::iter()。我在类型和迭代器方面遇到了问题(我还不太擅长迭代器)。这种方法迫使我将每个函数克隆/导出VecDequeLimVecDeque. 大量的工作!

第二种方法:创建一个新特征并实施VecDeque

trait Limited {
  type Elem;

  pub fn push_bounded(&self, limit: usize, elem: Elem);
}
Run Code Online (Sandbox Code Playgroud)

然后再实现 的特征VecDeque。 …

collections deque rust

5
推荐指数
1
解决办法
1555
查看次数

如何有效地将切片复制到 Rust VecDeque 中

我正在以流方式处理字节输入,如下所示:

pub struct CharQueue<R: Read> {
    reader: R,
    deque: VecDeque<u8>,
    buf: [u8;1024],
}
Run Code Online (Sandbox Code Playgroud)
self.deque.reserve_exact(bytes_read);
for i in 0..bytes_read {
    self.deque.push_back(self.buf[i]);
}
Run Code Online (Sandbox Code Playgroud)

在分析中,它似乎VecDeque::cap()是运行时的主要贡献者。这是令人惊讶的,因为它除了返回一个变量(我猜还有分支)之外几乎什么都不做:

fn cap(&self) -> usize {
    if mem::size_of::<T>() == 0 {
        // For zero sized types, we are always at maximum capacity
        MAXIMUM_ZST_CAPACITY
    } else {
        self.buf.capacity()
    }
}
Run Code Online (Sandbox Code Playgroud)

所以它一定被调用了很多次(如果它在 inside 被调用push_back(),事后看来这很有意义)。

我想知道是否有一种方法可以将整个缓冲区一次性复制到队列中,因此容量只需检查并增加一次。.reserve_exact()跳过中间分配,但不跳过检查和增量。.append()是这样的,但我必须先消耗缓冲区才能将其转换为另一个 VecDeque,但我不想这样做,因为我想重新使用它。我真正想要的是这样的东西push_back_slice(),只需要一个切片,增加队列长度/执行任何所需的分配一次,然后将切片的每个元素直接复制到可用空间中,而不改变或消耗它。

有没有办法做到这一点?

deque slice rust

5
推荐指数
1
解决办法
2027
查看次数

Rust 中的闭包捕获

我刚刚发现下面的代码

fn create_fn_once() -> impl FnOnce(char) -> String {
    let text = "text".to_string();  // not implement the `Copy` trait
    let y = 1;                      // implement the `Copy` trait

    |x| {
        move_x(text);   // ok
        move_x(y);      // error: `y` is borrowed here
        x.to_string()
    }
}

fn move_x<T: Sized>(x: T) {}
Run Code Online (Sandbox Code Playgroud)

失败(游乐场

error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
 --> src/lib.rs:5:5
  |
5 |     |x| {
  |     ^^^ may outlive …
Run Code Online (Sandbox Code Playgroud)

rust

5
推荐指数
1
解决办法
174
查看次数

优雅地处理 SIGTERM (Ctrl-c) 并关闭线程池

目前,我正在阅读 Rust 书的最后一章,实现 HTTP 服务器的正常关闭。

现在我想稍微扩展一下逻辑,并在按 Ctrl-c 后触发正常关闭。因此我使用ctrlc crate

但由于各种借用检查器错误,我无法使其工作:

fn main() {
    let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
    let pool = ThreadPool::new(4);

    ctrlc::set_handler(|| {
        // dropping will trigger ThreadPool::drop and gracefully shutdown the running workers
        drop(pool); // compile error, variable is moved here
    })
    .unwrap();

    for stream in listener.incoming() {
        let stream = stream.unwrap();

        pool.execute(|| {
            handle_connection(stream);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试了使用Arc<>和附加mpsc 通道的多种方法,但没有成功。

为了使其发挥作用,最佳实践是什么?

concurrency rust

5
推荐指数
1
解决办法
2010
查看次数

`use std::error::Error` 声明会破坏编译

我编写了一个小函数来记录整个堆栈跟踪,如下所示:

fn report_error(error: &Box<dyn std::error::Error>, message: &str) {
    let mut error_msg = Vec::<String>::new();
    error_msg.push(message.to_string());
    if let Some(source) = error.source() {
        error_msg.push("caused by:".into());
        for (i, e) in std::iter::successors(Some(source), |e| e.source()).enumerate() {
            error_msg.push(format!("\t{}: {}", i, e));
        }
    }
    tracing::error!("{}", error_msg.join("\n"));
}
Run Code Online (Sandbox Code Playgroud)

该代码可以在 rustc 1.67.1 上编译并运行良好。但是,一旦我use std::error::Error;在顶部添加声明,编译就会失败,并出现以下错误:

   Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
 --> src/lib.rs:8:63
  |
8 |         for (i, e) in std::iter::successors(Some(source), |e| e.source()).enumerate() {
  |                                                            -- ^^^^^^^^^^ returning this value requires that `'1` must …
Run Code Online (Sandbox Code Playgroud)

rust

5
推荐指数
1
解决办法
92
查看次数

传递给异步回调的引用的生命周期

我有一个异步函数,我正在向其传递异步回调。回调将引用作为参数。

use core::future::Future;

async fn foo(bar: &u32) {}

async fn baz<F, Fut>(f: F)
where
    F: FnOnce(&u32) -> Fut,
    Fut: Future<Output = ()>,
{
    let test: u32 = 42;
    f(&test).await;
}

#[tokio::main]
async fn main() {
    baz(foo).await;
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试构建这个(游乐场) ,我会收到以下错误:

error[E0308]: mismatched types
  --> src/main.rs:16:5
   |
16 |     baz(foo).await;
   |     ^^^ lifetime mismatch
   |
   = note: expected associated type `<for<'_> fn(&u32) -> impl Future<Output = ()> {foo} as FnOnce<(&u32,)>>::Output`
              found associated type `<for<'_> fn(&u32) -> impl Future<Output = ()> {foo} …
Run Code Online (Sandbox Code Playgroud)

rust

4
推荐指数
1
解决办法
858
查看次数

匹配多种可能的类型?

我对 Rust 非常非常陌生,并且由于我强大的弱类型编程背景,我一直在努力解决它。

下面的代码应将通过 PYO3 从 Python 接收的数据写入 XLSX 工作表中。我只是不知道如何处理最后一个匹配,因为“value”是 PyAny 类型(也就是说,它的方法 extract 可以输出多种类型,例如 String、f32 等,并且我想要根据提取的特定行为类型)。

也许我可以为每个潜在的提取类型链接匹配(如果第一个输出 Err,请尝试下一个),但我怀疑可能有更好的方法。也许我只是用错误的设计来解决这个问题。任何见解都将受到欢迎。

pub trait WriteValue {
    fn write_value(&self, worksheet: &mut Worksheet, row: u32, col: u16, format: Option<&Format>) -> Result<(), XlsxError>;
}

impl WriteValue for String {
    fn write_value(&self, worksheet: &mut Worksheet, row: u32, col: u16, format: Option<&Format>) -> Result<(), XlsxError> {
        worksheet.write_string(row, col, &self, format)
    }
}

impl WriteValue for f32 {
    fn write_value(&self, worksheet: &mut Worksheet, row: u32, col: u16, format: Option<&Format>) -> …
Run Code Online (Sandbox Code Playgroud)

match rust xlsxwriter pyo3

4
推荐指数
1
解决办法
770
查看次数

查看“for”循环内的迭代器

我正在尝试查看当前位置前面的字符,同时迭代&str.

\n
let myStr = "12345";\nlet mut iter = myStr.chars().peekable();\nfor c in iter {\n    let current: char = c;\n    let next: char = *iter.peek().unwrap_or(&\'\xe2\x88\x85\');\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我将把这个字符传递到一个方法中。然而,即使这个 MRE 也会产生移动后借用错误,我不知道如何克服该错误。

\n
error[E0382]: borrow of moved value: `iter`\n   --> src/lib.rs:7:27\n    |\n4   |     let mut iter = myStr.chars().peekable();\n    |         -------- move occurs because `iter` has type `Peekable<Chars<\'_>>`, which does not implement the `Copy` trait\n5   |     for c in iter {\n    |              ---- `iter` moved due to this implicit call to `.into_iter()`\n6   | …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

4
推荐指数
1
解决办法
788
查看次数

在 Rust 中使用 unwrap_or_else 进行错误处理

我有一个 Rust 程序,它有一个函数\n\xe2\x80\x98is_input_sanitized\xe2\x80\x99,它接受输入\n字符串 m,并检查输入是否不含特殊字符。该方法正在单独使用按以下方式运行。

\n
let a = match is_input_sanitized(m) {\n  Ok(m) => m,\n  Err(_) => { return Err("error"); },\n};\n
Run Code Online (Sandbox Code Playgroud)\n

我正在尝试将此片段转换为使用 \xe2\x80\x98unwrap_or_else\xe2\x80\x99 ,当输入未清理时,它将返回错误。我已阅读文档,但无法破译实现的正确方法这。这种转换可能吗?

\n

rust

4
推荐指数
1
解决办法
4442
查看次数

我怎样才能让assert_eq! 在 Rust 中显示多行字符串

我有以下 Rust 单元测试:

    #[test]
    fn test_multiline_strings_are_equal() {
        let expected = "\
one
two
three
four
";
        let actual = "\
one
two
four
";
        assert_eq!(actual, expected);
    }
Run Code Online (Sandbox Code Playgroud)

当失败时,会输出以下内容:

---- printer::tests::test_multiline_strings_are_equal stdout ----
thread 'printer::tests::test_multiline_strings_are_equal' panicked at 'assertion failed: `(left == right)`
  left: `"one\ntwo\nfour\n"`,
 right: `"one\ntwo\nthree\nfour\n"`', src\printer.rs:600:9
Run Code Online (Sandbox Code Playgroud)

谁能告诉我如何让它在不同的行上显示“一”、“二”、“三”和“四”,以便于比较?

rust

4
推荐指数
1
解决办法
681
查看次数

标签 统计

rust ×10

deque ×2

borrow-checker ×1

collections ×1

concurrency ×1

match ×1

pyo3 ×1

slice ×1

xlsxwriter ×1