我正在阅读Rust for Rustaceans,它讨论了零大小类型在库的API建模中的使用,它给出了应用程序的框架,但没有显示实际的实现,当我尝试实现它时,它失败了。
我需要帮助实现默认值,因为它现在抱怨我在创建对象时没有为stage提供值。我实际上认为,因为它是PhantomData,所以我不必提供任何值。
我还需要帮助实现launch。我希望能够只返回self来重用现有对象,但它抱怨它是一个不同的类型。强制转换self as Rocket<Launched>
也不起作用。
让这个 backbone 工作的正确方法是什么?
struct Grounded;
struct Launched;
struct Rocket<Stage = Grounded> {
stage: std::marker::PhantomData<Stage>,
}
impl Default for Rocket<Grounded> {
fn default() -> Self { }
}
impl Rocket<Grounded> {
pub fn launch(self) -> Rocket<Launched> { }
}
impl Rocket<Launched> {
pub fn accelerate(&mut self) { println!("Accelerating"); }
pub fn decelerate(&mut self) { println!("Decelerating"); }
}
impl<Stage> Rocket<Stage> {
pub fn color(&self) { println!("blue"); }
pub fn weight(&self) { println!("10kg"); }
}
fn main() {
let rocket: Rocket = Default::default();
}
1条答案
按热度按时间aiazj4mn1#
每个字段都必须初始化,这对于ZST字段(如
PhantomData
)也是如此。您可以这样做:您可以通过直接导出
Default
来删除其中的一些样板文件:因为
Rocket<Grounded>
和Rocket<Launched>
是两种不同的类型,你不能用一个初始化另一个。你必须创建一个新的火箭:尽管还不清楚为什么需要
PhantomData
,因为这些级已经是ZST,而且都是works just fine without it