我想实现一个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()。我在类型和迭代器方面遇到了问题(我还不太擅长迭代器)。这种方法迫使我将每个函数克隆/导出VecDeque到LimVecDeque. 大量的工作!
第二种方法:创建一个新特征并实施VecDeque:
trait Limited {
type Elem;
pub fn push_bounded(&self, limit: usize, elem: Elem);
}
Run Code Online (Sandbox Code Playgroud)
然后再实现 的特征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(),只需要一个切片,增加队列长度/执行任何所需的分配一次,然后将切片的每个元素直接复制到可用空间中,而不改变或消耗它。
有没有办法做到这一点?
我刚刚发现下面的代码
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 书的最后一章,实现 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 通道的多种方法,但没有成功。
为了使其发挥作用,最佳实践是什么?
我编写了一个小函数来记录整个堆栈跟踪,如下所示:
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) 我有一个异步函数,我正在向其传递异步回调。回调将引用作为参数。
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 非常非常陌生,并且由于我强大的弱类型编程背景,我一直在努力解决它。
下面的代码应将通过 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) 我正在尝试查看当前位置前面的字符,同时迭代&str.
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}\nRun Code Online (Sandbox Code Playgroud)\n我将把这个字符传递到一个方法中。然而,即使这个 MRE 也会产生移动后借用错误,我不知道如何克服该错误。
\nerror[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 程序,它有一个函数\n\xe2\x80\x98is_input_sanitized\xe2\x80\x99,它接受输入\n字符串 m,并检查输入是否不含特殊字符。该方法正在单独使用按以下方式运行。
\nlet a = match is_input_sanitized(m) {\n Ok(m) => m,\n Err(_) => { return Err("error"); },\n};\nRun Code Online (Sandbox Code Playgroud)\n我正在尝试将此片段转换为使用 \xe2\x80\x98unwrap_or_else\xe2\x80\x99 ,当输入未清理时,它将返回错误。我已阅读文档,但无法破译实现的正确方法这。这种转换可能吗?
\n我有以下 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)
谁能告诉我如何让它在不同的行上显示“一”、“二”、“三”和“四”,以便于比较?