Rust中Struct方法创建及所有权移动报错的解决办法
解决Rust中Struct初始化时的所有权移动问题
你的代码出现use of moved value错误,核心原因是:DaysOfTheWeekNames枚举没有实现Copy trait,当你在Self { day, ... }中使用day时,变量的所有权已经被转移到结构体的day字段里,后续调用Weekday::isWeekend(day)时,这个变量已经不再属于当前作用域,因此报错。
同时注意你原来的isWeekend逻辑是反的——周六周日应该被判定为周末(返回true),下面的解决方案会一并修正这个问题。
方案一:给枚举添加Copy和Clone派生宏
你的枚举是无关联数据的单元枚举,完全可以安全地复制。通过派生Copy和Clone,传递参数时会自动复制一份,不会转移所有权:
#[derive(Debug, Copy, Clone)] enum DaysOfTheWeekNames { Friday, Saturday, Sunday, } #[derive(Debug)] struct Weekday { day: DaysOfTheWeekNames, weekend: bool, } impl Weekday { fn is_weekend(day: DaysOfTheWeekNames) -> bool { matches!(day, DaysOfTheWeekNames::Saturday | DaysOfTheWeekNames::Sunday) } fn new_day(day: DaysOfTheWeekNames) -> Self { Self { day, weekend: Self::is_weekend(day) } } } fn main() { let today = Weekday::new_day(DaysOfTheWeekNames::Saturday); println!("Today: {:#?}", today); }
这里用matches!宏简化了周末判断的逻辑,同时遵循Rust的蛇形命名规范把isWeekend改成is_weekend。
方案二:让is_weekend接收引用而非所有权
如果不想给枚举添加Copy,可以修改方法参数为引用类型,这样只借用变量而不转移所有权:
#[derive(Debug)] enum DaysOfTheWeekNames { Friday, Saturday, Sunday, } #[derive(Debug)] struct Weekday { day: DaysOfTheWeekNames, weekend: bool, } impl Weekday { fn is_weekend(day: &DaysOfTheWeekNames) -> bool { matches!(day, DaysOfTheWeekNames::Saturday | DaysOfTheWeekNames::Sunday) } fn new_day(day: DaysOfTheWeekNames) -> Self { Self { day, weekend: Self::is_weekend(&day) } } } fn main() { let today = Weekday::new_day(DaysOfTheWeekNames::Saturday); println!("Today: {:#?}", today); }
这种方式更适合无法实现Copy的复杂枚举,同样能解决所有权问题。
方案三:调整执行顺序(不推荐)
如果必须转移所有权给is_weekend,可以让方法返回判定结果和原变量,再用于结构体初始化,但这种写法冗余,一般不推荐:
#[derive(Debug)] enum DaysOfTheWeekNames { Friday, Saturday, Sunday, } #[derive(Debug)] struct Weekday { day: DaysOfTheWeekNames, weekend: bool, } impl Weekday { fn is_weekend(day: DaysOfTheWeekNames) -> (bool, DaysOfTheWeekNames) { let is_weekend = matches!(&day, DaysOfTheWeekNames::Saturday | DaysOfTheWeekNames::Sunday); (is_weekend, day) } fn new_day(day: DaysOfTheWeekNames) -> Self { let (weekend, day) = Self::is_weekend(day); Self { day, weekend } } } fn main() { let today = Weekday::new_day(DaysOfTheWeekNames::Saturday); println!("Today: {:#?}", today); }
推荐写法
优先选择方案一,因为单元枚举实现Copy/Clone没有任何副作用,代码最简洁直观,完全符合你的需求。
内容的提问来源于stack exchange,提问作者imharjyotbagga
相关产品推荐
相关产品推荐

