Rust Quizes解答
关于Rust语法的测试题,题目来源Rust Quiz。
一
What is the output of this Rust program?
1 | macro_rules! m { |
答案:112。
m宏匹配唯一一个分支模式($($s:stmt)*),它表示匹配任意数量的statement。statement在Rust中可以解释为:
- 变量,如
x - 语句,如
let x = 5; - 表达式,如
{ 5 }
宏展开时,使用<<作为连接符,由于表达式末尾的1,宏展开时每个匹配的值为固定的1。换而言之,宏的值为匹配的数量减1的2次幂。
在题目中展示的三个宏调用中,第一个宏调用中的return || true表示返回一个闭包,故其只有一个statement,值为1。
第二个宏调用中,(return)为一个元组,是一个值,(return) || true是一个表达式,故只有一个statement,值为1。
第三个宏调用中,{ return } || true被解析为两个表达式:一个单独的块表达式{return}和闭包|| true。在宏展开后,它的表达式如下:
1 | { stringfy!("{ return }"; 1)} << { stringfy!("|| true"); 1} |
也就是
1 | 1 << 1 |
综上,本题的解答为112。
二
What is the output of this Rust program?
1 | struct S(i32); |
答案:123。
f中(() & S(1))将运算后的值作为闭包的结果,所以它会计算()&S(1)。g同理。h中,空表达式默认返回值为(),最外层的()使得空表达式仍与S(3)进行计算。
但是,在i中,{}本身并不会直接参与到计算中,类似于
1 | { |
表达式的值会被直接抛弃,所以i中的&运算符表示引用,没有发生计算。
综上,本题的解答为123。
三
What is the output of this Rust program?
1 | struct S { |
答案:32
在rust中的const常量类似于C中的#define,它并不保存一个值,而是在被调用时做表达式替换。
题目中的代码实际上等价于:
1 | struct S { |
四
What is the output of this Rust program?
1 | fn main() { |
答案是:54。
在rust中,..有两个含义:
- 在表达式中,
..表示RangeFull类型的变量,例如v[..]表示v的一个完整切片。 - 在模式匹配中,
..表示任意数量的元素。
在本题中,(.., x, y)可以匹配任意元素数量大于等于2的元组,并将其最后两个元素赋值给x和y,因此x值为1,y值为..。
输出表达式为b"066"[y][x],也就是b"066"[..][1],而b"066"是[u8; 3],我们会先获取一个完整的切片,再输出第二个元素,也就是b'6',其ASCII码为54。
六
What is the output of this Rust program?
1 | use std::mem; |
答案:0。
在第二个let语句中事实上发生了变量覆盖,可以看作let a = { a = true };,其为变量a赋值了一个表达式,这个表达式的值是一个语句,也就是说实际值为()。()不占用任何空间,所以结果是0。
七
What is the output of this Rust program?
1 |
|
答案:1。
在这里的match匹配中,First表示匹配成功后的变量名,而不是枚举值,所以总是匹配到First分支。
八
What is the output of this Rust program?
1 | macro_rules! m { |
答案:1214。
在宏的模式匹配中,符号串会从左到右被解析为合法符号的集合。在这四个案例中,四个符号分别解析为:
- 等于,大于
- 赋值,赋值,大于
- 等于,大于
- 等于,胖箭头
可见3与1的含义一致,会优先匹配到1,因此输出1214。
九
What is the output of this Rust program?
1 | macro_rules! m { |
答案:21
显然,t!(1)会展开为e!(1);m!(1);。
其中,e!(1)可以匹配第一个分支。然而,虽然事实上$e是1,但是它不能匹配第一个m的分支,因为在展开时,对于m来说,$e就是一个表达式,不能匹配第一个分支,所以输出2。但是m!($tt)可以匹配,因为$tt描述符是一个特殊的描述符。
在rust宏中,有三类描述符可以在匹配后继续匹配值:
$:ident$:lifetime$:tt
十
What is the output of this Rust program?
1 | trait Trait { |