如何 return 具有来自函数的 String 类型字段的结构的 Vec?
How to return a Vec of structs that have a String type field from a function?
我正在开发一个具有函数 lex
的词法分析器,它应该将扫描标记的向量移动到一个主程序,然后主程序将生成一个解析器来解析标记,定义如下:
/// ### lex
/// Pushes the tokens generated by
/// `scan_token` to `self.tokens`
fn lex(&mut self) -> Vec<Token> {
while !Self::is_at_eof(self) {
self.lexeme_start = self.lookahead;
self.tokens.push(Self::scan_token(self).unwrap());
}
self.tokens
.push(Token::new(TokenType::EOF, String::from(""), self.row));
self.tokens
}
向量 self.tokens: Vec<Token>
应包含定义为
的标记
pub struct Token {
// -- snip of copyable fields --
lexeme: String, // <-- the issue
// -- snip of copyable fields --
}
但是,这不会编译,因为 String
类型没有实现 Copy
特性。在将所有权传递给函数调用者(如移动它)时,我如何 return 这个向量?
我知道这个函数不是public,所以它不能被模块外的任何东西调用,但一旦我测试成功它就会被调用。
However, this will not compile, as the String type does not implement the Copy trait. How might I return this vector while passing ownership to the function caller (as in move it)?
你……不能?这真的没有意义,为什么你们都将令牌流存储在自己身上并 returning 它?一个或另一个是有意义的(毕竟调用者可以根据需要从标记器获取标记)。或者,如果您希望能够,比如说,出于某种原因进行链式调用,您可以 return 一个 reference 到 Self
所拥有的令牌流。
/// Option 0: return a reference to the Vec (could be mutable, so you could push into it)
fn lex0(&mut self) -> &Vec<Token> {
while !self.is_at_eof() {
self.lexeme_start = self.lookahead;
self.scan_token();
}
self.tokens.push(Token::new(TokenType::EOF, String::from(""), self.row));
&self.tokens
}
/// Option 1: return a slice reference (could be mutable, couldn't push into it)
fn lex1(&mut self) -> &[Token] {
while !self.is_at_eof() {
self.lexeme_start = self.lookahead;
self.scan_token();
}
self.tokens.push(Token::new(TokenType::EOF, String::from(""), self.row));
&self.tokens
}
或者,按值获取 self
以便使用它,这样您就可以在销毁后者时 将 令牌从 self
中移出.
/// Option 2: consume lexer and return tokens stream
fn lex2(mut self) -> Vec<Token> {
while !self.is_at_eof() {
self.lexeme_start = self.lookahead;
self.scan_token();
}
self.tokens.push(Token::new(TokenType::EOF, String::from(""), self.row));
self.tokens
}
最后,您可以在 Token
上实现 Clone
,并将整个 Vec 克隆到 return,但这似乎效率不高。
#[derive(Clone)]
struct Token {...}
/// Option 3: copy tokens stream
fn lex3(&mut self) -> Vec<Token> {
while !self.is_at_eof() {
self.lexeme_start = self.lookahead;
self.scan_token();
}
self.tokens.push(Token::new(TokenType::EOF, String::from(""), self.row));
self.tokens.clone()
}
不真正了解潜在需求是什么,很难提供好的建议。
我正在开发一个具有函数 lex
的词法分析器,它应该将扫描标记的向量移动到一个主程序,然后主程序将生成一个解析器来解析标记,定义如下:
/// ### lex
/// Pushes the tokens generated by
/// `scan_token` to `self.tokens`
fn lex(&mut self) -> Vec<Token> {
while !Self::is_at_eof(self) {
self.lexeme_start = self.lookahead;
self.tokens.push(Self::scan_token(self).unwrap());
}
self.tokens
.push(Token::new(TokenType::EOF, String::from(""), self.row));
self.tokens
}
向量 self.tokens: Vec<Token>
应包含定义为
pub struct Token {
// -- snip of copyable fields --
lexeme: String, // <-- the issue
// -- snip of copyable fields --
}
但是,这不会编译,因为 String
类型没有实现 Copy
特性。在将所有权传递给函数调用者(如移动它)时,我如何 return 这个向量?
我知道这个函数不是public,所以它不能被模块外的任何东西调用,但一旦我测试成功它就会被调用。
However, this will not compile, as the String type does not implement the Copy trait. How might I return this vector while passing ownership to the function caller (as in move it)?
你……不能?这真的没有意义,为什么你们都将令牌流存储在自己身上并 returning 它?一个或另一个是有意义的(毕竟调用者可以根据需要从标记器获取标记)。或者,如果您希望能够,比如说,出于某种原因进行链式调用,您可以 return 一个 reference 到 Self
所拥有的令牌流。
/// Option 0: return a reference to the Vec (could be mutable, so you could push into it)
fn lex0(&mut self) -> &Vec<Token> {
while !self.is_at_eof() {
self.lexeme_start = self.lookahead;
self.scan_token();
}
self.tokens.push(Token::new(TokenType::EOF, String::from(""), self.row));
&self.tokens
}
/// Option 1: return a slice reference (could be mutable, couldn't push into it)
fn lex1(&mut self) -> &[Token] {
while !self.is_at_eof() {
self.lexeme_start = self.lookahead;
self.scan_token();
}
self.tokens.push(Token::new(TokenType::EOF, String::from(""), self.row));
&self.tokens
}
或者,按值获取 self
以便使用它,这样您就可以在销毁后者时 将 令牌从 self
中移出.
/// Option 2: consume lexer and return tokens stream
fn lex2(mut self) -> Vec<Token> {
while !self.is_at_eof() {
self.lexeme_start = self.lookahead;
self.scan_token();
}
self.tokens.push(Token::new(TokenType::EOF, String::from(""), self.row));
self.tokens
}
最后,您可以在 Token
上实现 Clone
,并将整个 Vec 克隆到 return,但这似乎效率不高。
#[derive(Clone)]
struct Token {...}
/// Option 3: copy tokens stream
fn lex3(&mut self) -> Vec<Token> {
while !self.is_at_eof() {
self.lexeme_start = self.lookahead;
self.scan_token();
}
self.tokens.push(Token::new(TokenType::EOF, String::from(""), self.row));
self.tokens.clone()
}
不真正了解潜在需求是什么,很难提供好的建议。