Rust 包含单元格值副本的所有权
我目前正致力于创建“在Go中编写解释器”中描述的编程语言,但我正在尝试用Rust编写代码 我有以下表示lexer的结构:Rust 包含单元格值副本的所有权,rust,Rust,我目前正致力于创建“在Go中编写解释器”中描述的编程语言,但我正在尝试用Rust编写代码 我有以下表示lexer的结构: struct Lexer<'a> { input: &'a [u8], // assume the text input is all ascii curr_pos: Cell<usize>, read_pos: Cell<usize>, curr_char: Cell<char>, }
struct Lexer<'a> {
input: &'a [u8], // assume the text input is all ascii
curr_pos: Cell<usize>,
read_pos: Cell<usize>,
curr_char: Cell<char>,
}
我得到了一个关于值&self.curr\u char.get().to\u string()
的错误,该值活得不够长。所有权规则是如何在这里发挥作用的?什么是“给予”一个标记其价值的最佳方式
以下是完整的代码:
use std::cell::Cell;
use std::str;
use std::char;
#[derive(Debug, PartialEq)]
enum TokenType<'a> {
ILLEGAL,
EOF,
IDENT(&'a str),
INT(i64),
ASSIGN,
PLUS,
COMMA,
SEMICOLON,
LPAREN,
RPAREN,
LBRACE,
RBRACE,
FUNCTION,
LET,
}
struct Token<'a> {
tokenType: TokenType<'a>,
literal: &'a str,
}
struct Lexer<'a> {
input: &'a [u8], // assume the text input is all ascii
curr_pos: Cell<usize>,
read_pos: Cell<usize>,
curr_char: Cell<char>,
}
impl<'a> Lexer<'a> {
fn next_token(&self) -> Token {
const NULL_CHAR: char = 0 as char;
let token = match self.curr_char.get() {
'=' => Token {tokenType: TokenType::ASSIGN, literal: &self.curr_char.get().to_string()},
';' => Token {tokenType: TokenType::SEMICOLON, literal: &self.curr_char.get().to_string()},
'(' => Token {tokenType: TokenType::LPAREN, literal: &self.curr_char.get().to_string()},
')' => Token {tokenType: TokenType::RPAREN, literal: &self.curr_char.get().to_string()},
'{' => Token {tokenType: TokenType::LBRACE, literal: &self.curr_char.get().to_string()},
'}' => Token {tokenType: TokenType::RBRACE, literal: &self.curr_char.get().to_string()},
',' => Token {tokenType: TokenType::COMMA, literal: &self.curr_char.get().to_string()},
'+' => Token {tokenType: TokenType::PLUS, literal: &self.curr_char.get().to_string()},
'\0' => Token {tokenType: TokenType::EOF, literal: &self.curr_char.get().to_string()},
}
}
}
使用std::cell::cell;
使用std::str;
使用std::char;
#[派生(调试,部分Q)]
枚举标记类型,
字面:&'a str,
}
结构Lexer{
fn下一个\u令牌(&self)->令牌{
常量NULL_CHAR:CHAR=0作为CHAR;
让token=match self.curr\u char.get()匹配{
'='=>Token{tokenType:tokenType::ASSIGN,literal:&self.curr\u char.get().to\u string()},
“;”=>标记{tokenType:tokenType::分号,文字:&self.curr\u char.get().to\u string()},
“('=>Token{tokenType:tokenType::LPAREN,literal:&self.curr\u char.get().to\u string()},
“)”=>Token{tokenType:tokenType::RPAREN,literal:&self.curr\u char.get().to\u string()},
“{'=>Token{tokenType:tokenType::LBRACE,literal:&self.curr\u char.get().to\u string()},
'}'=>Token{tokenType:tokenType::RBRACE,literal:&self.curr\u char.get().to\u string()},
“,”=>Token{tokenType:tokenType::逗号,literal:&self.curr\u char.get().to\u string()},
“+”=>Token{tokenType:tokenType::PLUS,literal:&self.curr\u char.get().to\u string()},
'\0'=>Token{tokenType:tokenType::EOF,literal:&self.curr\u char.get().to\u string()},
}
}
}
@Shepmaster可以,很抱歉,我没有仔细研究变量命名约定,所以我一直在混淆它们。和literal=表示标记的字符串literal,我不知道我是如何错误地使用它的。从编程语言的角度来说,它不是字面意思。“字面类型”-现在我认为你使用这个术语与一般意义不同了。文字是“foo”
或'x'
或123
。&self.curr\u char.get().to\u string()
中没有文本。我理解为什么我不能构建一个字符串并返回&str
——但是您发布的代码正试图构建一个字符串并返回一个&str
,所以请帮助我们找出缺少的解释部分。单元格
与此无关to_string
创建一个新的、拥有的字符串,正如其签名所示:curr_char
单元格中包含的值是char
类型-yes。返回一个char
type-yes。正如trentcl指出的那样,在字符上调用到_string()
——分配一个全新的字符串。就像建议的复制品一样,通过to_String
创建一个新的字符串。
Token {tokenType: TokenType::ASSIGN, literal: &self.curr_char.get().to_string()}
use std::cell::Cell;
use std::str;
use std::char;
#[derive(Debug, PartialEq)]
enum TokenType<'a> {
ILLEGAL,
EOF,
IDENT(&'a str),
INT(i64),
ASSIGN,
PLUS,
COMMA,
SEMICOLON,
LPAREN,
RPAREN,
LBRACE,
RBRACE,
FUNCTION,
LET,
}
struct Token<'a> {
tokenType: TokenType<'a>,
literal: &'a str,
}
struct Lexer<'a> {
input: &'a [u8], // assume the text input is all ascii
curr_pos: Cell<usize>,
read_pos: Cell<usize>,
curr_char: Cell<char>,
}
impl<'a> Lexer<'a> {
fn next_token(&self) -> Token {
const NULL_CHAR: char = 0 as char;
let token = match self.curr_char.get() {
'=' => Token {tokenType: TokenType::ASSIGN, literal: &self.curr_char.get().to_string()},
';' => Token {tokenType: TokenType::SEMICOLON, literal: &self.curr_char.get().to_string()},
'(' => Token {tokenType: TokenType::LPAREN, literal: &self.curr_char.get().to_string()},
')' => Token {tokenType: TokenType::RPAREN, literal: &self.curr_char.get().to_string()},
'{' => Token {tokenType: TokenType::LBRACE, literal: &self.curr_char.get().to_string()},
'}' => Token {tokenType: TokenType::RBRACE, literal: &self.curr_char.get().to_string()},
',' => Token {tokenType: TokenType::COMMA, literal: &self.curr_char.get().to_string()},
'+' => Token {tokenType: TokenType::PLUS, literal: &self.curr_char.get().to_string()},
'\0' => Token {tokenType: TokenType::EOF, literal: &self.curr_char.get().to_string()},
}
}
}