Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何使用&;调用方法;从同一类型的另一个方法内部执行mut self?_Rust - Fatal编程技术网

Rust 如何使用&;调用方法;从同一类型的另一个方法内部执行mut self?

Rust 如何使用&;调用方法;从同一类型的另一个方法内部执行mut self?,rust,Rust,我有一个Scannerstruct,它实现了scan(&mut self)方法。看起来像这样 pub struct Scanner { input: String, output: Vec<String>, state: ScannerState, } impl Scanner { pub fn scan(&mut self) { self.state = ScannerState::CharMode; for

我有一个
Scanner
struct,它实现了
scan(&mut self)
方法。看起来像这样

pub struct Scanner {
    input: String,
    output: Vec<String>,
    state: ScannerState,
}

impl Scanner {
    pub fn scan(&mut self) {
        self.state = ScannerState::CharMode;
        for character in self.input.chars() {
            match character {
                i @ '0'...'9'   => self.output.push(format!("Integer digit: {}", i)),
                '+'             => self.output.push("Addition operator: +".to_string()),
                '-'             => self.output.push("Subtraction operator: -".to_string()),
                '*'             => self.output.push("Multiplication operator: *".to_string()),
                '/'             => self.output.push("Division operator: /".to_string()),
                '%'             => self.output.push("Modulus operator: %".to_string()),
                '^'             => self.output.push("Exponent operator: ^".to_string()),
                '='             => self.output.push("Assignment operator: =".to_string()),
                ';'             => self.output.push("Statement terminator: ;".to_string()),
                c @ 'a'...'z'| c @ 'A'...'Z'
                                => self.output.push(format!("Variable name: {}", c)),
                ' '             => self.output.push("Space, ignoring.".to_string()),
                z @ _           => self.output.push(format!("Unrecognized token: {}", z))
            }
        }
    }        
}
但是等等!我们不能那样做,Rust告诉我们:

src/scanner.rs:34:17: 34:21 error: cannot borrow `*self` as mutable because `self.input` is also borrowed as immutable
src/scanner.rs:34                 self.char_match(character);
                                  ^~~~
然而,我们的
char\u match()
方法需要有一个对
self
的可变引用,因为它推送,并且
push()
Vec
上执行需要可变性。那么,我的问题是,根据前面的知识,补救这种情况的理想方法是什么?


我是否只需要编写
scan()
作为一个长方法?

char\u match
不需要对
self
进行可变访问。对
self.output
self.state
的可变访问就足够了。如果您不授予它访问
self.input
的权限,编译器将不再抱怨。

我的建议是将
char\u match
设置为无状态:

pub fn scan(&mut self) {
    self.state = ScannerState::CharMode;

    while self.state == ScannerState::CharMode {
        for character in self.input.chars() {
            match char_match(character) {
                Some(string) => self.output.push(string),
                None => self.state = ScannerState::QuitMode
            }
        }
        self.state = ScannerState::Done;
    }
}

fn char_match(c: char) -> Option<String> {
    Some(match c {
        '+' => "Addition operator: +".into(),
        '-' => "Subtraction operator: -".into(),
        '*' => "Multiplication operator: *".into(),
        '/' => "Division operator: /".into(),
        '%' => "Modulus operator: %".into(),
        '^' => "Exponent operator: ^".into(),
        '=' => "Assignment operator: =".into(),
        ';' => "Statement terminator: ;".into(),
        ' ' => "Space, ignoring.".into(),

        'q' => return None,

        i @ '0'...'9' => format!("Integer digit: {}", i),
        c @ 'a'...'z' => format!("Variable name: {}", c),
        z @ _         => format!("Unrecognized token: {}", z)
    })
}
pub-fn扫描(&mut-self){
self.state=ScannerState::CharMode;
而self.state==ScannerState::CharMode{
对于self.input.chars()中的字符{
匹配字符\u匹配(字符){
Some(string)=>self.output.push(string),
无=>self.state=ScannerState::QuitMode
}
}
self.state=扫描状态::完成;
}
}
fn字符匹配(c:char)->选项{
一些(比赛c){
“+”=>“加法运算符:+”.into(),
“-”=>“减法运算符:-”.into(),
“*”=>“乘法运算符:*”.into(),
“/”=>“除法运算符:/”.into(),
“%”=>“模运算符:%”。into(),
“^'=>”指数运算符:^“,
“=”=>“赋值运算符:=”.into(),
“;”=>“语句终止符:;”.into(),
''=>“空格,忽略。“.into(),
'q'=>返回无,
i@'0'…'9'=>格式!(“整数位数:{},i),
c@'a'…'z'=>格式!(“变量名:{},c),
z@=>format!(“无法识别的标记:{}”,z)
})
}

这避免了完全借用,也更容易组合。

(对未来读者)避免在>q'/COD>之前的所有静态字符串的分配和拷贝,然后考虑使用和返回<代码>选项
pub fn scan(&mut self) {
    self.state = ScannerState::CharMode;

    while self.state == ScannerState::CharMode {
        for character in self.input.chars() {
            match char_match(character) {
                Some(string) => self.output.push(string),
                None => self.state = ScannerState::QuitMode
            }
        }
        self.state = ScannerState::Done;
    }
}

fn char_match(c: char) -> Option<String> {
    Some(match c {
        '+' => "Addition operator: +".into(),
        '-' => "Subtraction operator: -".into(),
        '*' => "Multiplication operator: *".into(),
        '/' => "Division operator: /".into(),
        '%' => "Modulus operator: %".into(),
        '^' => "Exponent operator: ^".into(),
        '=' => "Assignment operator: =".into(),
        ';' => "Statement terminator: ;".into(),
        ' ' => "Space, ignoring.".into(),

        'q' => return None,

        i @ '0'...'9' => format!("Integer digit: {}", i),
        c @ 'a'...'z' => format!("Variable name: {}", c),
        z @ _         => format!("Unrecognized token: {}", z)
    })
}