学习写解析模块中的不解
为什么while let Some(&ch) = self.source.peek() {
中的 Some(&ch)
要使用 &ch
而不是 ch
❓
//7.读取一串数字存入buffer,即如 123
fn read_digits_to_buffer(&mut self) {
while let Some(&ch) = self.source.peek() {
match ch {
'0'..='9' => {
self.buffer.push(ch);
self.source.next();
},
_ => break,
}
}
}
🗝️在Rust中,Peekable
迭代器的peek
方法返回的是对集合中下一个元素的不可变引用,而不是元素本身。这是因为peek
方法允许你查看下一个元素而不从迭代器中移除它,所以它只能提供一个对该元素的引用。
在你的代码中,self.source.peek()
的返回值是Option<&char>
类型,即一个可能存在的对字符的引用。因此,在match
表达式中使用&ch
是为了直接解构出这个引用,使ch
成为一个char
类型的变量,而不是一个引用。如果使用ch
而不是&ch
,那么ch
将是&char
类型,你需要在使用ch
时额外进行解引用操作,这样代码会更加繁琐。
简而言之,使用&ch
可以直接在match
的分支中使用ch
作为char
类型,而不是&char
,这样可以使代码更简洁、易于理解。
为什么 match label
这里要使用 as_ref()
方法?如果不使用会怎样?
//9.核心函数,逐字符解析source,并返回Token类型
fn next(&mut self) -> JsonResult<Token> {
while let Some(ch) = self.source.next() {
return Ok(match ch {
',' => Token::Comma,
':' => Token::Colon,
'[' => Token::BracketOn,
']' => Token::BracketOff,
'{' => Token::BraceOn,
'}' => Token::BraceOff,
'"' => Token::String(self.read_string(ch)?),
'0'..='9' | '-' => Token::Number(self.read_number(ch)?),
'a'..='z' => {
let label = self.read_label(ch);
match label.as_ref() {
"true" => Token::Boolean(true),
"false" => Token::Boolean(false),
"null" => Token::Null,
_ => {
return Err(JsonError::UnexpectedToken(label.clone()));
}
}
},
_ => {
if ch.is_whitespace() {
continue;
} else {
return Err(JsonError::UnexpectedCharacter(ch));
}
},
});
}
Err(JsonError::UnexpectedEndOfJson)
}
🗝️在这段代码中,label
是通过 self.read_label(ch)
方法返回的,这个方法的返回类型是 &String
,即 label
是一个对 String
的引用。
在 Rust 中,当你想要比较字符串或者将字符串用作字典的键时,通常需要一个字符串切片 &str
而不是 String
或者 &Strin
g。方法 as_ref()
被用于将 &String
类型转换为 &str
类型,这使得它可以直接与字面量字符串(如 “true
”、“false
” 和 “null
”)进行比较。
如果不使用 as_ref()
方法,你将尝试直接使用 &String
类型与 &str
类型进行比较,这在 Rust 中是不允许的,因为它们是不同的类型。如果尝试这样做,编译器将会报错,提示类型不匹配。
简而言之,使用 as_ref()
是为了类型兼容性,确保可以正确地进行字符串比较。
本站中有一部分来源于网络和媒体的内容(文章、源码、软件应用、资源附件等),并尽可能的标出参考来源、出处,本站尊重原作者的成果,若本站内容侵犯了您的合法权益时或者对转载内容有疑义的内容原作者,请书面反馈并提供确切的个人身份证明与详细资料信息在第一时间以邮件形式进行联系沟通;