gpt4 book ai didi

rust - 跨迭代移动不可复制的结构

转载 作者:行者123 更新时间:2023-11-29 08:23:49 25 4
gpt4 key购买 nike

我正在尝试访问 for 循环中的变量。我无法在该结构上实现 Copy,因为它包含一个 String。我将如何跨迭代使用变量?

编译时出现错误 E0382。当我查看 Rust 的错误文档时,他们提到使用引用计数来解决问题。这是我的唯一解决方案吗?

#[derive(Clone)]
struct InputParser {
args: Vec<String>,
current: String,
consumed_quote: bool,
}

impl InputParser {
pub fn parse(input: String) -> Vec<String> {
let parser = InputParser {
args: Vec::new(),
current: String::new(),
consumed_quote: false,
};
for c in input.chars() {
match c {
'"' => parser.consume_quote(),
' ' => parser.consume_space(),
_ => parser.consume_char(c),
}
}
parser.end();

return parser.args;
}

pub fn consume_space(mut self) {
if !self.consumed_quote {
self.push_current();
}
}

pub fn consume_quote(mut self) {
self.consumed_quote = self.consumed_quote;
if self.consumed_quote {
self.push_current();
}
}

pub fn consume_char(mut self, c: char) {
self.current.push(c);
}

pub fn end(mut self) {
self.push_current();
}

pub fn push_current(mut self) {
if self.current.len() > 0 {
self.args.push(self.current);
self.current = String::new();
}
}
}

我想在 for 循环的迭代中访问 parser

最佳答案

[How do I] move [a] non-copyable struct across iterations

没有,至少不是微不足道的。一旦将结构移至函数,它就消失了。取回它的唯一方法是让函数将它还给您。

相反,您很可能想修改循环内的现有结构。您需要为此使用可变引用:

use std::mem;

#[derive(Clone)]
struct InputParser {
args: Vec<String>,
current: String,
consumed_quote: bool,
}

impl InputParser {
fn consume_space(&mut self) {
if !self.consumed_quote {
self.push_current();
}
}

fn consume_quote(&mut self) {
self.consumed_quote = self.consumed_quote;
if self.consumed_quote {
self.push_current();
}
}

fn consume_char(&mut self, c: char) {
self.current.push(c);
}

fn end(&mut self) {
self.push_current();
}

fn push_current(&mut self) {
if self.current.len() > 0 {
let arg = mem::replace(&mut self.current, String::new());
self.args.push(arg);
}
}
}

fn parse(input: String) -> Vec<String> {
let mut parser = InputParser {
args: Vec::new(),
current: String::new(),
consumed_quote: false,
};
for c in input.chars() {
match c {
'"' => parser.consume_quote(),
' ' => parser.consume_space(),
_ => parser.consume_char(c),
}
}
parser.end();

parser.args
}

fn main() {}

请注意,以前采用当前参数的方式会导致 error[E0507]: cannot move out of borrowed content,所以我切换到 mem::replace .这可以防止 self.current 成为未定义的值(以前是)。


如果你真的想按值传递所有东西,你也需要按值返回。

#[derive(Clone)]
struct InputParser {
args: Vec<String>,
current: String,
consumed_quote: bool,
}

impl InputParser {
fn consume_space(mut self) -> Self {
if !self.consumed_quote {
return self.push_current();
}
self
}

fn consume_quote(mut self) -> Self {
self.consumed_quote = self.consumed_quote;
if self.consumed_quote {
return self.push_current();
}
self
}

fn consume_char(mut self, c: char) -> Self {
self.current.push(c);
self
}

fn end(mut self) -> Self {
self.push_current()
}

fn push_current(mut self) -> Self {
if self.current.len() > 0 {
self.args.push(self.current);
self.current = String::new();
}
self
}
}

fn parse(input: String) -> Vec<String> {
let mut parser = InputParser {
args: Vec::new(),
current: String::new(),
consumed_quote: false,
};
for c in input.chars() {
parser = match c {
'"' => parser.consume_quote(),
' ' => parser.consume_space(),
_ => parser.consume_char(c),
}
}
parser = parser.end();

parser.args
}

fn main() {}

我相信在这种情况下,这会使 API 客观上变得更糟。但是,您会经常在 builder 中看到这种样式。在那种情况下,这些方法往往会链接在一起,因此您永远不会看到对变量的重新分配。

关于rust - 跨迭代移动不可复制的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42610685/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com