我很难理解为什么该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()换句话说,当调用该方法时,什么会发生变化?
似乎在派生时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) 在调试会话期间,我发现了一个问题,我能够减少到这个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) 我正在用 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字符串中的它解释为新行?
该函数返回一个闭包。用作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)
为什么最后两个例子不起作用?
我正在实现 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) 我试图实现我自己的自定义 SpinLock,但 SpinLock 似乎行为不当。
\n我有两个文件,main.rs并且safe.rs.
测试在 Ubuntu 22.04.3LTS 中进行,系统规格为 4GB RAM、64 位处理器、AMD\xc2\xae Pro a4-3350b APU 和 Radeon r4 显卡。
\n这是错误消息:
\nloki@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\nRun Code Online (Sandbox Code Playgroud)\nsafe.rs:
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)