AST 도 IR 도 본질이 태그드 유니온이다. 태그 비교만 되고 안을 꺼내지 못하면
검사 없이 필드를 읽어야 하고, 그러면 안전성 이야기가 통째로 무너진다.
무언가를 담는 변이는 메모리다: 태그가 앞, 페이로드가 뒤. 태그를 읽는 것은
어느 쪽이든 같은 질문이고 자리만 다르다. 페이로드는 가리키지 않고 복사한다 --
매치한 것의 소유권을 arm 이 가져가는 것이 보통이고, 그게 허용되는지는 검사기가
이미 판단했다.
레코드 변이의 필드 오프셋을 아무도 기록하지 않고 있었다. 레이아웃이 크기는
재면서 자리는 버렸다.
Enum.Variant{...} 와 Enum.Variant(x) 와 페이로드 없는 Enum.Variant 를 모두
만든다. 마지막 것은 페이로드를 가진 enum 안에서는 태그만 든 값이다.
some 7 / none / point 3 4 / empty
exec.py 25/25.
36 lines
734 B
Plaintext
36 lines
734 B
Plaintext
// 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;
|
|
}
|