枚举如何使用堆或堆栈类型处理其子类型?

问题标题可能有点误导,因为我不知道如何正确表达我的意思。

这是问题所在。我有这段代码,它按预期工作。

enum Answer {
    Yes,
    No(i32),
}

pub struct QnA {
    question: String,
    answer: Answer,
}

fn check(qna: &QnA) {
    match qna.answer {
        Answer::Yes => println!("positive"),
        Answer::No(why) => println!("negative cause {}", why),
    }
}

我感兴趣的是那match部分。假设我将枚举更改为Answer这样的内容,

enum Answer {
    Yes,
    No(String),
}

比赛将不再有效。它说它不能移出引用后面的东西。为了使它工作,我必须&qna.answer在比赛中使用引用。

我知道错误只发生在堆使用的类型上。所以我可以得到一个提示,这是因为所有权系统,但我无法直观地弄清楚枚举和结构之间的关系。我不知道枚举如何使用堆或堆栈处理其子类型。

回答

我知道错误只发生在堆使用的类型上。

这是不真实的。错误发生在没有实现的类型上Copy,这意味着它们必须被移动。i32和大多数其他原语实现Copy,这意味着您可以自由地对引用进行模式匹配并隐式复制非引用值。但是,对于Copy像 那样的非值String,隐式复制不再发生,并且您尝试将值移出引用,这是不允许的。

看:

  • Rust 编程语言:什么是所有权?
  • Rust by example:所有权和移动
  • Rust 文档:我的类型Copy什么时候可以是?(以及随后的“我的类型何时不能Copy?”和“我的类型何时应该Copy?”)

顺便提一下,Rust 的类型系统没有区分堆类型和堆栈类型,因为它们是不必要的区别。堆只是一块内存,就像某些内存分配器决定使用的堆栈一样,而在核心库中,没有堆分配器。通常,只有堆栈上的类型才能实现Copy,因为这些类型复制起来很便宜,而堆内存必须重新分配。然而,这并不是说栈上的每个类型都实现了Copy(你可以在栈上创建一个结构体而不在它上面实现 Copy),或者堆上没有类型实现Copy(你可以有一个自定义的分配器或垃圾收集器) )。

  • I think that the OP confusion comes from the Book saying (in that chapter you link): "Rust has a special annotation called the Copy trait that we can place on types like integers that are stored on the stack". It seems to equal stack-allocated with `Copy`.

以上是枚举如何使用堆或堆栈类型处理其子类型?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>