Rust 包含单元格值副本的所有权

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>, }

我目前正致力于创建“在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>,
}
我得到了一个关于值
&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()},
        }
    }
}