lower: 태그드 유니온을 해체한다 -- match 페이로드와 if let
AST 도 IR 도 본질이 태그드 유니온이다. 태그 비교만 되고 안을 꺼내지 못하면
검사 없이 필드를 읽어야 하고, 그러면 안전성 이야기가 통째로 무너진다.
무언가를 담는 변이는 메모리다: 태그가 앞, 페이로드가 뒤. 태그를 읽는 것은
어느 쪽이든 같은 질문이고 자리만 다르다. 페이로드는 가리키지 않고 복사한다 --
매치한 것의 소유권을 arm 이 가져가는 것이 보통이고, 그게 허용되는지는 검사기가
이미 판단했다.
레코드 변이의 필드 오프셋을 아무도 기록하지 않고 있었다. 레이아웃이 크기는
재면서 자리는 버렸다.
Enum.Variant{...} 와 Enum.Variant(x) 와 페이로드 없는 Enum.Variant 를 모두
만든다. 마지막 것은 페이로드를 가진 enum 안에서는 태그만 든 값이다.
some 7 / none / point 3 4 / empty
exec.py 25/25.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
// EXIT:0
|
||||
// OUTPUT:some 7
|
||||
// OUTPUT:none
|
||||
// OUTPUT:point 3 4
|
||||
// OUTPUT:empty
|
||||
unit patterns;
|
||||
|
||||
enum Shape {
|
||||
Empty,
|
||||
Point(i32),
|
||||
Pair { x: i32, y: i32 },
|
||||
}
|
||||
|
||||
fn pick(flag: bool) -> ?i32 {
|
||||
if flag { return 7; }
|
||||
return null;
|
||||
}
|
||||
|
||||
fn describe(s: Shape) -> void {
|
||||
match s {
|
||||
Empty => { @print("empty\n"); }
|
||||
Point(v) => { @print("point {}\n", v); }
|
||||
Pair { x, y } => { @print("point {} {}\n", x, y); }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> i32 {
|
||||
if let Some(v) = pick(true) { @print("some {}\n", v); }
|
||||
else { @print("unexpected\n"); }
|
||||
if let None = pick(false) { @print("none\n"); }
|
||||
else { @print("unexpected\n"); }
|
||||
describe(Shape.Pair{ x: 3, y: 4 });
|
||||
describe(Shape.Empty);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user