学习Rust时遭遇栈溢出问题,求排查思路
Rust栈溢出问题分析(DrinkSize的Display实现)
你遇到的栈溢出问题,几乎可以肯定是在DrinkSize枚举的Display trait实现的fmt函数中发生了无限递归。
常见错误场景
最典型的错误是在fmt方法里,不小心用{}格式化了self,导致递归调用自身的fmt函数:
use std::fmt; enum DrinkSize { Small, Medium, Large, } impl fmt::Display for DrinkSize { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // 错误:此处会触发无限递归 write!(f, "{}", self) } }
当你调用write!(f, "{}", self)时,Rust会自动调用self的Display实现——也就是当前正在编写的fmt函数。这个过程会无限重复,每次递归都会在栈上创建新的函数调用帧,直到栈空间被耗尽,最终触发栈溢出。
正确的实现方式
你需要直接匹配枚举的变体,将对应的字符串写入格式化器,避免递归调用:
use std::fmt; enum DrinkSize { Small, Medium, Large, } impl fmt::Display for DrinkSize { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { DrinkSize::Small => write!(f, "Small"), DrinkSize::Medium => write!(f, "Medium"), DrinkSize::Large => write!(f, "Large"), } } }
额外检查点
如果你的代码不是上述直接递归的情况,还需要排查:
- 是否在
fmt中调用了其他函数,而该函数又间接调用了DrinkSize的Display实现 - 是否在栈上分配了过大的数据结构(不过这种情况很少会刚好停在
fmt函数处)
内容的提问来源于stack exchange,提问作者Daniel Konopka
相关产品推荐
相关产品推荐

