/* ===== 模块4:match 语句 ===== * test18_match — match 枚举匹配 + 整数匹配(类似 switch) * 难度:3/5 * 验证点:枚举匹配、带数据绑定、结构体字段绑定、枚举指针、 * 整数自变量匹配、默认分支 _ */ /* ---- 简单枚举(无数据) ---- */ type Color = enum { Red; Green; Blue; } /* ---- 带 i32 数据的枚举 ---- */ type Optional = enum { Some: i32; None; } /* ---- 带结构体数据的枚举 ---- */ type Point = struct { var x: i32; var y: i32; } type Shape = enum { Circle: i32; Rect: Point; } /* ---- 多变体枚举 ---- */ type ActionResult = enum { Success: i32; NotFound; Timeout: i32; Error: *u8; } /* ============================================================ * 测试 1: 无数据枚举匹配 * ============================================================ */ fn test_color_match() i32 { var c: Color = Color { .Red }; var val: i32 = 0; match c { .Red => { val = 1; }, .Green => { val = 2; }, .Blue => { val = 3; } } if val != 1 { ret 1; } c = Color { .Green }; match c { .Red => { val = 0; }, .Green => { val = 2; }, .Blue => { val = 0; } } if val != 2 { ret 2; } c = Color { .Blue }; match c { .Red => { val = 0; }, .Green => { val = 0; }, .Blue => { val = 3; } } if val != 3 { ret 3; } ret 0; } /* ============================================================ * 测试 2: 带 i32 数据枚举匹配 * ============================================================ */ fn test_optional_match() i32 { var o: Optional = Optional { .Some = 42 }; match o { .Some(val) => { if val != 42 { ret 1; } }, .None => { ret 2; } } o = Optional { .None }; var is_none: i32 = 0; match o { .Some(val) => {}, .None => { is_none = 1; } } if is_none != 1 { ret 3; } /* 多次提取不同值 */ o = Optional { .Some = 99 }; match o { .Some(val) => { if val != 99 { ret 4; } }, .None => { ret 5; } } ret 0; } /* ============================================================ * 测试 3: 带结构体数据枚举匹配(多字段绑定) * ============================================================ */ fn test_shape_match() i32 { /* Circle: 单数据 */ var s: Shape = Shape { .Circle = 10 }; match s { .Circle(r) => { if r != 10 { ret 1; } }, .Rect(w, h) => { ret 2; } } /* Rect: 结构体数据,绑定为 (x, y) 对应 Point 的字段 */ s = Shape { .Rect = Point { .x = 3, .y = 4 } }; match s { .Circle(r) => { ret 3; }, .Rect(w, h) => { if w != 3 { ret 4; } if h != 4 { ret 5; } } } ret 0; } /* ============================================================ * 测试 4: 多数据变体枚举匹配 * ============================================================ */ fn test_action_result_match() i32 { var r: ActionResult = ActionResult { .Success = 200 }; match r { .Success(code) => { if code != 200 { ret 1; } }, .NotFound => { ret 2; }, .Timeout(ms) => { ret 3; }, .Error(msg) => { ret 4; } } r = ActionResult { .NotFound }; var found: i32 = 1; match r { .Success(code) => { found = 0; }, .NotFound => { }, .Timeout(ms) => { found = 0; }, .Error(msg) => { found = 0; } } if found != 1 { ret 5; } r = ActionResult { .Timeout = 5000 }; match r { .Success(code) => { ret 6; }, .NotFound => { ret 7; }, .Timeout(ms) => { if ms != 5000 { ret 8; } }, .Error(msg) => { ret 9; } } ret 0; } /* ============================================================ * 测试 5: 枚举指针匹配 * ============================================================ */ fn test_ptr_match() i32 { var c: Color = Color { .Green }; var p: *Color = &c; match p { .Red => { ret 1; }, .Green => { }, .Blue => { ret 2; } } /* 修改后通过指针匹配 */ c = Color { .Blue }; match p { .Red => { ret 3; }, .Green => { ret 4; }, .Blue => { } } ret 0; } /* ============================================================ * 测试 6: match 作为函数返回值 * ============================================================ */ fn classify_color(c: Color) i32 { match c { .Red => { ret 1; }, .Green => { ret 2; }, .Blue => { ret 3; } } ret 0; } fn test_match_in_func() i32 { var r: i32; r = classify_color(Color { .Red }); if r != 1 { ret 1; } r = classify_color(Color { .Green }); if r != 2 { ret 2; } r = classify_color(Color { .Blue }); if r != 3 { ret 3; } ret 0; } /* ============================================================ * 测试 7: match 嵌套在循环中 * ============================================================ */ fn test_match_in_loop() i32 { var i: i32 = 0; var sum: i32 = 0; while i < 3 { var o: Optional; if i == 0 { o = Optional { .Some = 10 }; } else if i == 1 { o = Optional { .Some = 20 }; } else { o = Optional { .Some = 30 }; } match o { .Some(val) => { sum = sum + val; }, .None => { } } i = i + 1; } if sum != 60 { ret 1; } ret 0; } /* ============================================================ * 测试 8: 整数 match(类似 switch) * ============================================================ */ fn test_int_match() i32 { var x: i32 = 2; var result: i32 = 0; match x { 1 => { result = 10; }, 2 => { result = 20; }, 3 => { result = 30; } } if result != 20 { ret 1; } /* 匹配第一个值 */ x = 1; match x { 1 => { result = 100; }, 2 => { result = 200; }, 3 => { result = 300; } } if result != 100 { ret 2; } /* 匹配最后一个值 */ x = 3; match x { 1 => { result = 1000; }, 2 => { result = 2000; }, 3 => { result = 3000; } } if result != 3000 { ret 3; } ret 0; } /* ============================================================ * 测试 9: 整数 match 带默认分支 _ * ============================================================ */ fn test_int_match_default() i32 { var x: i32 = 99; var result: i32 = 0; match x { 1 => { result = 1; }, 2 => { result = 2; }, _ => { result = 99; } } if result != 99 { ret 1; } /* 默认分支未触发 */ x = 1; match x { 1 => { result = 1; }, 2 => { result = 2; }, _ => { result = 99; } } if result != 1 { ret 2; } ret 0; } /* ============================================================ * 测试 10: 整数 match 多个值跳转到相同逻辑 * ============================================================ */ fn test_int_match_multi() i32 { var x: i32 = 2; var result: i32 = 0; /* 每个分支独立 */ match x { 0 => { result = 0; }, 1 => { result = 1; }, 2 => { result = 2; }, 3 => { result = 3; } } if result != 2 { ret 1; } /* 负数和零 */ x = -1; match x { -1 => { result = -1; }, 0 => { result = 0; }, 1 => { result = 1; } } if result != -1 { ret 2; } x = 0; match x { -1 => { result = -1; }, 0 => { result = 0; }, 1 => { result = 1; } } if result != 0 { ret 3; } ret 0; } /* ============================================================ * 测试 11a: match 多值 fallthrough: 1, 2, 3 => body * ============================================================ */ fn test_int_match_fallthrough() i32 { var x: i32; var r: i32; /* 三个值映射到同一个 body */ x = 1; r = 0; match x { 1, 2, 3 => { r = 10; }, 4, 5 => { r = 20; } } if r != 10 { ret 1; } x = 3; match x { 1, 2, 3 => { r = 10; }, 4, 5 => { r = 20; } } if r != 10 { ret 2; } x = 5; match x { 1, 2, 3 => { r = 10; }, 4, 5 => { r = 20; } } if r != 20 { ret 3; } /* 单一值(非fallthrough)仍然正常 */ x = 7; r = 0; match x { 1 => { r = 1; }, 7 => { r = 7; } } if r != 7 { ret 4; } /* 多个负数值 */ x = -2; r = 0; match x { -3, -2, -1 => { r = 100; }, 0, 1 => { r = 200; } } if r != 100 { ret 5; } ret 0; } /* ============================================================ * 测试 11b: match with body 中修改变量 * ============================================================ */ fn test_match_with_side_effects() i32 { var x: i32 = 3; var acc: i32 = 0; match x { 1 => { acc = acc + 1; }, 2 => { acc = acc + 2; }, 3 => { acc = acc + 3; }, 4 => { acc = acc + 4; } } if acc != 3 { ret 1; } /* 再次 match 同一个变量 */ match x { 1 => { acc = acc + 1; }, 2 => { acc = acc + 2; }, 3 => { acc = acc + 3; }, 4 => { acc = acc + 4; } } if acc != 6 { ret 2; } ret 0; } /* ============================================================ * 主函数 * ============================================================ */ fn main() i32 { var r: i32; r = test_color_match(); if r != 0 { ret r; } r = test_optional_match(); if r != 0 { ret r + 10; } r = test_shape_match(); if r != 0 { ret r + 20; } r = test_action_result_match(); if r != 0 { ret r + 30; } r = test_ptr_match(); if r != 0 { ret r + 40; } r = test_match_in_func(); if r != 0 { ret r + 50; } r = test_match_in_loop(); if r != 0 { ret r + 60; } r = test_int_match(); if r != 0 { ret r + 70; } r = test_int_match_default(); if r != 0 { ret r + 80; } r = test_int_match_multi(); if r != 0 { ret r + 90; } r = test_match_with_side_effects(); if r != 0 { ret r + 100; } r = test_int_match_fallthrough(); if r != 0 { ret r + 110; } ret 0; }