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 | #[repr(u8)] |
答案: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 { |