Go语言声明结构体map测试用例报错排查及代码优化咨询
错误修复
你的报错来自useCases函数的语法错误:函数返回值的类型声明未完成就开始定义局部变量,原代码中你写了func useCases() map[string]struct {之后直接开始定义tests变量,相当于编译器认为你还在定义返回值的结构体字段,自然无法识别:=符号。
另外你定义的high_number用例的want值是浮点格式,和业务函数返回的int类型不匹配,会触发类型错误,需要改成18阶乘对应的准确整数值。
修复后的完整测试代码如下:
package firstFactorial import ( "testing" "github.com/google/go-cmp/cmp" ) // 提前定义用例结构体类型,避免重复写匿名结构体 type testCase struct { input int want int } func useCases() map[string]testCase { return map[string]testCase{ "regular_number": {input: 3, want: 6}, // 18!的准确整数值为6402373705728000,不要用浮点格式避免精度/类型问题 "high_number": {input: 18, want: 6402373705728000}, "zero": {input: 0, want: 1}, "one": {input: 1, want: 1}, } } func TestRegular(t *testing.T) { for name, tc := range useCases() { t.Run(name, func(t *testing.T) { got := firstFactorial(tc.input) if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("%s 测试不通过,差异:%s", name, diff) } }) } } func TestRecursive(t *testing.T) { for name, tc := range useCases() { t.Run(name, func(t *testing.T) { got := firstFactorialRecursive(tc.input, 1) if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("%s 测试不通过,差异:%s", name, diff) } }) } }
代码精简优化建议
- 提取公共测试逻辑:两个测试函数的执行逻辑完全一致,仅调用的业务函数不同,可以提取为辅助函数减少重复代码:
func testFactorial(t *testing.T, fn func(int) int) { tests := map[string]testCase{ "regular_number": {input: 3, want: 6}, "high_number": {input: 18, want: 6402373705728000}, "zero": {input: 0, want: 1}, "one": {input: 1, want: 1}, } for name, tc := range tests { t.Run(name, func(t *testing.T) { got := fn(tc.input) if tc.want != got { t.Fatalf("%s: 期望 %d, 实际 %d", name, tc.want, got) } }) } }
对应的两个测试函数可以简化为:
func TestRegular(t *testing.T) { testFactorial(t, firstFactorial) } func TestRecursive(t *testing.T) { // 封装递归函数,隐藏第二个初始参数,符合func(int) int的签名 testFactorial(t, func(n int) int { return firstFactorialRecursive(n, 1) }) }
- 优化递归函数对外接口:当前递归函数需要调用方传入初始值1,使用体验较差,可以改成单参数的对外函数,内部调用私有递归实现。
- 移除不必要的依赖:你的测试场景仅需要比较int类型相等,不需要引入
go-cmp第三方库,直接用==判断即可,减少项目依赖。 - 去掉代码中不必要的分号,Go会自动在行尾补充分号,不需要手动编写。
内容的提问来源于stack exchange,提问作者Patrick.SE
相关产品推荐
相关产品推荐

