【发布时间】:2021-04-02 00:15:29
【问题描述】:
我一直在玩 rust,我正在做一个非常愚蠢的程序,它结合了特征、结构、一些愚蠢的并发和泛型。在我在线程之间发送特征时遇到一些问题之前,一切对我来说都是可以理解的。
首先,我意识到我需要一个 Boxed Animals 向量来存储符合 Animal trait 的不同元素,好吧,我明白了,因为 trait 是一些其他特定结构的抽象,这些结构可以在“大小”等方面有所不同,因此我们必须将它们存储在堆中。 但是对我来说第一个奇怪的点是,因为我必须使用 Box 来存储特征,所以我还必须为 Boxed 特征实现我的特征(参见代码 cmets 上的 (*1))。
一旦我这样做了,程序对于编译器来说是正确的,但是我在运行时遇到了一些我不明白的问题。 我得到的错误是:
thread '<unknown>' has overflowed its stack
fatal runtime error: stack overflow
[1] 4175 abort (core dumped) cargo run
代码是:
use std::thread;
use std::sync::mpsc::{Sender};
use std::sync::mpsc;
use std::time;
trait Animal {
fn poop(&self) -> Poop;
}
#[derive(Debug)]
enum Weight {
VeryLight,
Light,
Medium,
Heavy,
SuperHeavy,
}
#[derive(Debug)]
struct Poop {
shape: String,
weight: Weight,
}
struct Wombat;
impl Animal for Wombat {
fn poop(&self) -> Poop {
Poop {
shape: "cubic".to_string(),
weight: Weight::Light,
}
}
}
struct Cat;
impl Animal for Cat {
fn poop(&self) -> Poop {
Poop {
shape: "cylindrical".to_string(),
weight: Weight::VeryLight,
}
}
}
// (*1) This seemed weird for me and I'm not sure the
// impl es correct
impl Animal for Box<dyn Animal + Send> {
fn poop(&self) -> Poop {
let t: &dyn Animal = self;
// self.poop()
t.poop()
}
}
fn feed_animal<T> (a: T, tx: Sender<String>)
where T: Animal + Send + 'static {
thread::spawn(move || {
thread::sleep(time::Duration::from_secs(2));
tx.send(format!("{:?}", a.poop()))
});
}
fn main() {
let mut animals: Vec<Box<dyn Animal + Send>> = Vec::new();
animals.push(Box::new(Wombat));
animals.push(Box::new(Cat));
let (tx, rx) = mpsc::channel();
for a in animals {
let txi = tx.clone();
feed_animal(a, txi);
}
drop(tx);
for r in rx {
println!("The animal just pooped: {:?}", r);
}
}
老实说,我对错误消息有点迷茫。通常当我在其他一些编程语言中看到这种错误是由于无限循环会溢出堆栈,但在这种情况下,我想我将 Boxed 特征“发送”到子线程的方式一定有一些错误这使得 rust 在运行时无法很好地处理子线程堆栈内存。我不确定。
任何正确方向的提示都将受到欢迎。 谢谢。
【问题讨论】:
标签: rust