线程 'main' 在 Rust 中溢出了它的堆栈

Posted

技术标签:

【中文标题】线程 \'main\' 在 Rust 中溢出了它的堆栈【英文标题】:thread 'main' has overflowed its stack in Rust线程 'main' 在 Rust 中溢出了它的堆栈 【发布时间】:2020-05-24 21:53:48 【问题描述】:

我正在尝试学习 Rust(我来自 Java)并且遇到了一些问题。 我正在构建一个简单的程序,它是连接池的基础。 当我运行它时,我得到了运行时错误thread 'main' has overflowed its stack,我不明白为什么。

这里是 main.rs

use hello_rust::concurrent_bag;
use hello_rust::concurrent_bag::BagEntry;

fn main() 
    let my_bagentry = BagEntry::new(String::from("ciao"));
    //println!("", my_bagentry.value());
    let mut contVec : Vec<BagEntry<String>>=vec![];
    contVec.push(my_bagentry);
    println!("state =", contVec[0]);
    println!("state =", contVec[0].value());
    let mut my_bag: concurrent_bag::ConcurrentBag<String> =concurrent_bag::ConcurrentBag::new();
    my_bag.addEntry(String::from("ciao Entry"));
    let result = my_bag.borrowEntry();
    if result.is_some() 
    println!("", result.unwrap().value());
    

这里是 lib.rs

pub mod concurrent_bag 
    use crate::concurrent_bag::BagEntryState::UNUSED;

    pub enum BagEntryState 
        UNUSED, USED, REMOVED
    

    impl fmt::Display for BagEntryState 
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result 
            match *self 
                BagEntryState::UNUSED => write!(f, "UNUSED"),
                BagEntryState::USED => write!(f, "USED"),
                BagEntryState::REMOVED => write!(f, "REMOVED"),
            
        
    

    impl PartialEq for BagEntryState 
        fn eq(&self, other: &Self) -> bool 
            self == other
        
    

    pub struct BagEntry< T: std::cmp::PartialEq + fmt::Display> 
        state : BagEntryState,
        value: T,
    

    impl<'a, T: std::cmp::PartialEq + fmt::Display> BagEntry<T> 
        pub fn new(value: T) -> BagEntry< T> 
            BagEntry 
                value,
                state: UNUSED,
            
        

        pub fn value(&self)->&T 
            &self.value
        
        pub fn state(&self)->&BagEntryState 
            &self.state
        
    

    impl<'a, T: std::cmp::PartialEq + fmt::Display> PartialEq for BagEntry<T> 
        fn eq(&self, other: &Self) -> bool 
            self.value == other.value
        
    

    impl<T: std::cmp::PartialEq + fmt::Display> fmt::Display for BagEntry<T> 
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result 
            write!(f, "", self.value)
        
    

    use std::sync::Arc;
    use core::fmt;

    pub struct ConcurrentBag<T: std::cmp::PartialEq + fmt::Display> 
        entry_list:Vec<BagEntry<T>>,
    

    impl<'a, T:  std::cmp::PartialEq + fmt::Display> ConcurrentBag<T> 
        pub fn new() -> ConcurrentBag<T> 
            ConcurrentBag 
                entry_list: vec![],
            
        

        pub fn borrowEntry(&self) -> Option<BagEntry<T>> 
            println!("borrow vc size ", self.entry_list.len());
            println!("value =", (self).entry_list[0].value());
            println!("state =", (self).entry_list[0].state());
            if (self).entry_list[0].state()==&UNUSED 

            
            let result:Option<BagEntry<T>> =None;
            result
        

        pub fn addEntry(&mut self, value: T) 
            let my_bagentry = BagEntry::new(value);
            (*self).entry_list.push(my_bagentry);
            println!("addEntry vc size ", self.entry_list.len())
        

        pub fn removeEntry(&mut self, value: T) 
            let my_bagentry = BagEntry::new(value);
            let index =(*self).entry_list.iter().position(|x| *x == my_bagentry).unwrap();
            self.entry_list.remove(index);
        
    

有问题的行是

if (self).entry_list[0].state()==&UNUSED

我无法理解为什么因为这条线

println!("state =", (self).entry_list[0].state());

似乎运作良好。 另一个令我困惑的问题是,如果我在 borrowEntry 中使用&amp;self,我应该使用*self 来访问entry_list,但程序编译并运行没有错误。

【问题讨论】:

【参考方案1】:

这段代码不会永远重复吗?

impl PartialEq for BagEntryState 
    fn eq(&self, other: &Self) -> bool 
        self == other
    

我们实现了PartialEq,以便可以使用==!= 运算符比较一个类型的实例。所以,在那里使用self == other 是没有意义的。

你可以只推导出PartialEq

#[derive(PartialEq)]
pub enum BagEntryState 
    UNUSED,
    USED,
    REMOVED,

或者,如果你想手动实现它,你可以这样做。

impl PartialEq for BagEntryState 
    fn eq(&self, other: &BagEntryState) -> bool 
        match (self, other) 
            (&BagEntryState::UNUSED, &BagEntryState::UNUSED)
            | (&BagEntryState::USED, &BagEntryState::USED)
            | (&BagEntryState::REMOVED, &BagEntryState::REMOVED) => true,
            _ => false,
        
    

【讨论】:

你说得对,我在想这两个 ==(borrowEntry 中的那个和 PartialEq 中的那个)是不同的。

以上是关于线程 'main' 在 Rust 中溢出了它的堆栈的主要内容,如果未能解决你的问题,请参考以下文章

构造大树时“线程'<main>'已溢出其堆栈”

创建大型数组时,线程“<main>”已溢出其堆栈

算法main函数的堆栈溢出

如何解决 mysql 线程堆栈溢出?

ios堆栈溢出中的uuid,udid和设备令牌有啥区别

在 Windows 中调试堆栈溢出?