Rust中如何为Solve trait对象指定关联类型Answer?
问题核心原因
你遇到的类型不匹配,本质是具体类型包装的Box(比如Box<u32>、Box<String>)与 trait 对象包装的Box<dyn Display>是完全不同的类型。即便前者实现了Display trait,Rust也不会自动将它们视为等价类型,因此返回的trait对象要求Answer为Box<dyn Display>,但你的Solver实现用的是具体类型的Box,必然会报错。
解决方案一:统一关联类型为Box<dyn Display>
直接让所有实现Solve的结构体,将关联类型Answer统一设为Box<dyn Display>,在solve方法中返回具体值的Box时,Rust会自动将其转换为 trait 对象的Box:
use std::fmt::Display; fn main() { let solver = create_solver(2); let answer = solver.solve(); println!("{}", answer); } fn create_solver(kind: u32) -> Box<dyn Solve<Answer = Box<dyn Display>>> { match kind { 1 => Box::new(SolverOne), 2 => Box::new(SolverTwo), _ => unreachable!() } } trait Solve { type Answer: Display; fn solve(&self) -> Self::Answer; } struct SolverOne; impl Solve for SolverOne { type Answer = Box<dyn Display>; fn solve(&self) -> Self::Answer { Box::new(3) // 自动转换为Box<dyn Display> } } struct SolverTwo; impl Solve for SolverTwo { type Answer = Box<dyn Display>; fn solve(&self) -> Self::Answer { Box::new(String::from("three")) // 同样自动转换 } }
解决方案二:简化Trait(无需关联类型)
如果不需要保留关联类型的灵活性,可以直接修改trait Solve,让solve方法直接返回Box<dyn Display>,代码会更简洁:
use std::fmt::Display; fn main() { let solver = create_solver(2); let answer = solver.solve(); println!("{}", answer); } fn create_solver(kind: u32) -> Box<dyn Solve> { match kind { 1 => Box::new(SolverOne), 2 => Box::new(SolverTwo), _ => unreachable!() } } trait Solve { fn solve(&self) -> Box<dyn Display>; } struct SolverOne; impl Solve for SolverOne { fn solve(&self) -> Box<dyn Display> { Box::new(3) } } struct SolverTwo; impl Solve for SolverTwo { fn solve(&self) -> Box<dyn Display> { Box::new(String::from("three")) } }
内容的提问来源于stack exchange,提问作者stackcycle
相关产品推荐
相关产品推荐

