英文:
How to fix the following move error caused by variable assignment?
问题
以下是翻译好的部分:
以下的`Screen`结构体有处理`Input`枚举的方法:
#[derive(Debug)]
pub enum Input {
Text(String),
None,
Exit,
}
#[derive(Debug)]
pub enum InputError {
NotUTF8(Vec<u8>),
EmptyString,
IoError(std::io::Error),
}
struct Screen {
stdout: Vec<u8>,
}
impl Screen {
fn new(stdout: Vec<u8>) -> Self {
Screen { stdout }
}
fn print_input(self, input: Input) {
match input {
Input::Text(text) => {
println!("{}", &text);
}
Input::None => {
println!("None");
}
Input::Exit => {
println!("Exit");
}
}
}
fn handle_input(self, prompt: Option<String>) -> Result<Input, InputError> {
match prompt {
Some(_) => {
let input = get_input()?;
// 处理提示信息
Ok(input)
}
None => {
Ok(Input::None)
}
}
}
}
fn get_input() -> Result<Input, InputError> {
let input = "Text".to_owned();
Ok(Input::Text(input))
}
fn main() {
let screen = Screen::new(Vec::new());
let prompt = Some("Prompt".to_string());
let input = screen.handle_input(prompt);
screen.print_input(input.unwrap());
}
正如你所看到的,在`main()`函数中存在移动问题:
60 | let screen = Screen::new(Vec::new());
| ------ 移动发生在这里,因为`screen`的类型是`Screen`,它没有实现`Copy`特性
61 | let prompt = Some("Prompt".to_string());
62 | let input = screen.handle_input(prompt);
| -------------------- 由于这个方法调用导致`screen`被移动了
63 |
64 | screen.handle_input_result(input.unwrap());
| ^^^^^^ 在移动之后在这里使用了值
|
注意:`Screen::handle_input`方法接管了接收者`self`的所有权,因此移动了`screen`
如何修复这个问题?
请注意,上述翻译并没有包含代码部分。如果你需要完整的代码翻译,请提供额外的信息,我将为你提供完整的翻译。
英文:
The following Screen
struct has methods that handle the Input
enum:
#[derive(Debug)]
pub enum Input {
Text(String),
None,
Exit,
}
#[derive(Debug)]
pub enum InputError {
NotUTF8(Vec<u8>),
EmptyString,
IoError(std::io::Error),
}
struct Screen {
stdout: Vec<u8>,
}
impl Screen {
fn new(stdout: Vec<u8>) -> Self {
Screen { stdout }
}
fn print_input(self, input: Input) {
match input {
Input::Text(text) => {
println!("{}", &text);
}
Input::None => {
println!("None");
}
Input::Exit => {
println!("Exit");
}
}
}
fn handle_input(self, prompt: Option<String>) -> Result<Input, InputError> {
match prompt {
Some(_) => {
let input = get_input()?;
// do something with prompt
Ok(input)
}
None => {
Ok(Input::None)
}
}
}
}
fn get_input() -> Result<Input, InputError> {
let input = "Text".to_owned();
Ok(Input::Text(input))
}
fn main() {
let screen = Screen::new(Vec::new());
let prompt = Some("Prompt".to_string());
let input = screen.handle_input(prompt);
screen.print_input(input.unwrap());
}
As you can see, there's a move problem in main()
:
60 | let screen = Screen::new(Vec::new());
| ------ move occurs because `screen` has type `Screen`, which does not implement the `Copy` trait
61 | let prompt = Some("Prompt".to_string());
62 | let input = screen.handle_input(prompt);
| -------------------- `screen` moved due to this method call
63 |
64 | screen.handle_input_result(input.unwrap());
| ^^^^^^ value used here after move
|
note: `Screen::handle_input` takes ownership of the receiver `self`, which moves `screen`
--> src/main.rs:24:21
|
24 | fn handle_input(self, prompt: Option<String>) -> Result<Input, InputError> {
|
^^^^
How to fix it?
答案1
得分: 3
你将 self
传递给你的方法时是按值传递的,因此移动了你的 Screen
实例。你的方法不需要拥有 self
的所有权,所以可以改为通过引用传递 (&self
),从而修复所有权错误:
#[derive(Debug)]
pub enum Input {
Text(String),
None,
Exit,
}
#[derive(Debug)]
pub enum InputError {
NotUTF8(Vec<u8>),
EmptyString,
IoError(std::io::Error),
}
struct Screen {
stdout: Vec<u8>,
}
impl Screen {
fn new(stdout: Vec<u8>) -> Self {
Screen { stdout }
}
fn print_input(&self, input: Input) {
match input {
Input::Text(text) => {
println!("{}", &text);
}
Input::None => {
println!("None");
}
Input::Exit => {
println!("Exit");
}
}
}
fn handle_input(&self, prompt: Option<String>) -> Result<Input, InputError> {
match prompt {
Some(_) => {
let input = get_input()?;
// 处理提示的内容
Ok(input)
}
None => {
Ok(Input::None)
}
}
}
}
fn get_input() -> Result<Input, InputError> {
let input = "Text".to_owned();
Ok(Input::Text(input))
}
fn main() {
let screen = Screen::new(Vec::new());
let prompt = Some("Prompt".to_string());
let input = screen.handle_input(prompt);
screen.print_input(input.unwrap());
}
英文:
You pass self
to your methods by value, thus moving your Screen
instance. Your methods don't require ownership over self
, so you can just pass it by reference instead (&self
), fixing your ownership error:
#[derive(Debug)]
pub enum Input {
Text(String),
None,
Exit,
}
#[derive(Debug)]
pub enum InputError {
NotUTF8(Vec<u8>),
EmptyString,
IoError(std::io::Error),
}
struct Screen {
stdout: Vec<u8>,
}
impl Screen {
fn new(stdout: Vec<u8>) -> Self {
Screen { stdout }
}
fn print_input(&self, input: Input) {
match input {
Input::Text(text) => {
println!("{}", &text);
}
Input::None => {
println!("None");
}
Input::Exit => {
println!("Exit");
}
}
}
fn handle_input(&self, prompt: Option<String>) -> Result<Input, InputError> {
match prompt {
Some(_) => {
let input = get_input()?;
// do something with prompt
Ok(input)
}
None => {
Ok(Input::None)
}
}
}
}
fn get_input() -> Result<Input, InputError> {
let input = "Text".to_owned();
Ok(Input::Text(input))
}
fn main() {
let screen = Screen::new(Vec::new());
let prompt = Some("Prompt".to_string());
let input = screen.handle_input(prompt);
screen.print_input(input.unwrap());
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论