小编Fin*_*nis的帖子

为什么 std::iter::Peekable::peek 可变地借用 self 参数?

我很难理解为什么该peek()方法会可变地借用 self 参数。

文档

“返回对 next() 值的引用,而不推进迭代器。”

既然它没有推进迭代器,那么借用可变参数背后的意义是什么?

我查看了它的实现peek()并注意到它正在调用一个next()方法。

#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn peek(&mut self) -> Option<&I::Item> {
    let iter = &mut self.iter;
    self.peeked.get_or_insert_with(|| iter.next()).as_ref()
}
Run Code Online (Sandbox Code Playgroud)

是因为该next()方法的使用,该peek()方法被设计为可变借用,还是该peek()方法背后确实需要可变借用的另一种语义?

peek()换句话说,当调用该方法时,什么会发生变化?

rust

13
推荐指数
1
解决办法
620
查看次数

`#[derive(Clone)]` 似乎错误地将泛型强制为 `Clone`

似乎在派生时Clone,Rust 将Clone特征要求转发给不需要该特征的泛型,就像它们被包装在Arc.

我是否误解了Clone工作原理或者这是编译器错误?

考虑以下代码,其中a.clone()可行,但b.clone()不可行。另请注意,如果没有b.clone()调用,代码可以正常编译,表明可以#[derive(Clone)]正常工作。

use std::sync::Arc;

struct Unclonable {}

struct A<T>(Arc<T>);
impl<T> Clone for A<T> {
    fn clone(&self) -> Self {
        Self(self.0.clone())
    }
}

#[derive(Clone)]
struct B<T>(Arc<T>);

fn main() {
    let a = A(Arc::new(Unclonable {}));
    let b = B(Arc::new(Unclonable {}));

    // Works
    a.clone();
    // Fails
    b.clone();
}
Run Code Online (Sandbox Code Playgroud)
   |
3  | struct Unclonable {}
   | ----------------- doesn't satisfy `Unclonable: Clone`
...
13 | struct B<T>(Arc<T>); …
Run Code Online (Sandbox Code Playgroud)

generics rust

8
推荐指数
1
解决办法
778
查看次数

带有thread_local和std :: unordered_map的Segfault

在调试会话期间,我发现了一个问题,我能够减少到这个C++ 11代码:

#include <thread>
#include <vector>
#include <unordered_map>

class MyClass
{
    public:
        MyClass(){
            printf("%p\n", this);
        }
        ~MyClass(){
            printf("~%p\n", this);
        }

        std::unordered_map<int, int> member;
};

thread_local MyClass threadLocalObject;

int main(){
    std::vector<std::thread> threads;

    for (int i = 0; i < 40; ++i){
        threads.emplace_back([&](){
            printf("%ld\n", threadLocalObject.member.size());
        });
    }

    for (auto &thread : threads)
        thread.join();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用的编译器是g++-6 (Homebrew GCC 6.4.0) 6.4.0打开的MacOS 10.12.6.问题是它似乎在析构函数中崩溃了member.

但它并不总是崩溃,这让我想知道它是否是线程之间的某种竞争条件.

任何帮助表示赞赏,这让我感到疯狂.

我在Windows上与MinGW有类似的崩溃,所以我真的希望从了解这里发生的事情的人那里获得一些知识.

这是此代码中更激烈的崩溃日志之一:

0x7f9b2ba00228
0x7f9b2ac02728
0x7f9b2ba004e8
0x7f9b2ae00128
0x7f9b2b800128
0x7f9b2ad00128
0x7f9b2ac025f8
0x7f9b2ad00178
0x7f9b2b900138
0x7f9b2b800288 …
Run Code Online (Sandbox Code Playgroud)

c++ macos thread-safety c++11

6
推荐指数
0
解决办法
275
查看次数

解释从用户输入读取的字符串中的转义字符

我正在用 Rust 编写一个小型 CLI 应用程序。它处理用户输入,如果发现特殊转义字符,则需要对其进行解释。

例如,如果用户输入一个字符串'New\nLine',它应该被解释为:

这是我到目前为止的代码

fn main() {
    let text: Vec<String> = vec![String::from(r"New\n"), 
                                 String::from(r"Line")];
    slash_parser(text);
}


fn slash_parser(text: Vec<String>) {
    let mut text = text.join(" ");
    println!("{}", text); // ---> New\n Line
    if text.contains("\\") {
        text = str::replace(&text, r"\n", r"\\n");
        println!("{}", text); // ---> New\\n Line
        println!("New\nLine") // ---> New
                              // ---> Line
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为\在字符串中添加一个额外的内容会使其被解释为新行,但我显然错了。

由于某种原因,如果字符串作为参数传递,它将被解释为不带特殊字符的字符串。
但是,如果字符串被打印为字符串文字,则该\n符号将被解释为换行符。

我在这里理解错了什么,以及如何将\n字符串中的它解释为新行?

string newline escaping rust

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

将闭包指定为返回类型的其他方法?

该函数返回一个闭包。用作impl Fn()闭包类型就可以了:

fn foo() -> impl Fn() {
    || ()
}
Run Code Online (Sandbox Code Playgroud)

但这是行不通的:

fn foo<T: Fn()>() -> T {
    || ()
}
Run Code Online (Sandbox Code Playgroud)

也不是这个:

fn foo<T>() -> T
where
    T: Fn(),
{
    || ()
}
Run Code Online (Sandbox Code Playgroud)

为什么最后两个例子不起作用?

rust

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

相同数据的“&amp;[u32]”和“&amp;mut [u32]”的纯粹存在是否已被视为未定义行为?

我正在实现 SPI 驱动程序。

现在我有以下驱动程序代码(MRE 化):

use tokio::{join, sync::mpsc};

async fn spi_transmit(write_buf: &[u32], read_buf: &mut [u32]) {
    assert_eq!(read_buf.len(), write_buf.len());
    let (write_fifo, mut read_fifo) = mpsc::channel(2);

    let write_task = async {
        // Simulate an SPI bus that respondes with the sent data + 20,
        // just for demo purposes
        for val in write_buf {
            write_fifo.send(*val + 20).await.unwrap();
        }
    };

    let read_task = async {
        for val in read_buf {
            *val = read_fifo.recv().await.unwrap();
        }
    };

    join!(write_task, read_task);
}

#[tokio::main]
async fn main() { …
Run Code Online (Sandbox Code Playgroud)

rust

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

如何实现自旋锁

我试图实现我自己的自定义 SpinLock,但 SpinLock 似乎行为不当。

\n

我有两个文件,main.rs并且safe.rs.

\n

测试在 Ubuntu 22.04.3LTS 中进行,系统规格为 4GB RAM、64 位处理器、AMD\xc2\xae Pro a4-3350b APU 和 Radeon r4 显卡。

\n

这是错误消息:

\n
loki@loki:~/main/vs/actic/rust-nomic/spin-lock$ cargo run RUST_BACKTRACE=1\n   Compiling spin-lock v0.1.0 (/home/loki/main/vs/actic/rust-nomic/spin-lock)\n    Finished dev [unoptimized + debuginfo] target(s) in 0.98s\n     Running `target/debug/spin-lock RUST_BACKTRACE=1`\nHello, world!\nthread 'main' panicked at 'assertion failed: `(left == right)`\n  left: `9999995`,\n right: `10000000`', src/main.rs:15:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n
Run Code Online (Sandbox Code Playgroud)\n

safe.rs:

\n
use core::ops::{Deref,DerefMut};\nuse core::sync::atomic::{AtomicBool,Ordering::{Acquire,Release}};\nuse core::cell::UnsafeCell;\nuse core::hint::spin_loop;\n\n#[derive(Debug)]\npub struct …
Run Code Online (Sandbox Code Playgroud)

concurrency spinlock compare-and-swap rust

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