How to return a Vec of structs that have a String type field from a function?
我正在开发一个具有函数
1 2 3 4 5 6 7 8 9 10 11 12 | /// ### 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 } |
向量
的标记
1 2 3 4 5 | pub struct Token { // -- snip of copyable fields -- lexeme: String, // <-- the issue // -- snip of copyable fields -- } |
但是,这不会编译,因为
我知道这个函数不是公开的,所以它不能被模块外的任何东西调用,但是一旦我成功测试它就会调用它。
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)?
你……不能吗?这真的没有意义,为什么你们都将令牌流存储在 self 上并返回它?一个或另一个是有意义的(毕竟,如果调用者愿意,调用者可以从标记器中获取标记)。或者,如果您希望能够出于某种原因链接调用,您可以返回对
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /// 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 } |
或者,按值取
1 2 3 4 5 6 7 8 9 | /// 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 } |
最后你可以在
1 2 3 4 5 6 7 8 9 10 11 12 | #[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() } |
不知道潜在需求是什么,很难提供好的建议。