Go语言长度单位转换代码如何减少if/else且不丢失原有功能?
Go语言长度单位转换程序优化方案
核心优化思路
我们可以通过「基准单位中转」的思路彻底消除大量重复的if判断:所有长度单位都先转换为基准单位(米),再从基准单位转换为目标单位,只需要提前定义好每个单位和基准单位的换算系数即可,不需要单独为每一种组合写判断逻辑。
优化后代码
package main import "fmt" // 定义单位结构体,存储单位名称和与米的换算系数 type unit struct { name string factor float64 } // 预定义所有支持的单位,索引对应原来的用户选择1-4 var units = []unit{ {name: "Milimeters", factor: 0.001}, // 1 毫米:1mm = 0.001m {name: "Centimeters", factor: 0.01}, // 2 厘米:1cm = 0.01m {name: "Meters", factor: 1}, // 3 米 {name: "Kilometers", factor: 1000}, // 4 千米:1km = 1000m } // 通用用户选择输入函数,传入提示语,返回合法的选择索引(0开始) func getUserChoice(prompt string) int { var choice int for { fmt.Print(prompt) _, err := fmt.Scanln(&choice) if err == nil && choice >= 1 && choice <= len(units) { return choice - 1 // 转成0开头的索引对应units切片 } fmt.Println("INVALID CHOICE, please try again") } } func main() { fmt.Println("Welcome to GO METER app") // 选择源单位 srcPrompt := `1-Milimeter to 2-Centimeter to 3-Meter to 4-Kilometer to Please choose an operation: ` srcIdx := getUserChoice(srcPrompt) // 选择目标单位 dstPrompt := `1-to Milimeter 2-to Centimeter 3-to Meter 4-to Kilometer Please choose an operation: ` dstIdx := getUserChoice(dstPrompt) // 输入待转换数值 var num float64 fmt.Print("Enter the number you want to convert: ") fmt.Scanln(&num) // 统一换算:先转成米,再转成目标单位 srcUnit := units[srcIdx] dstUnit := units[dstIdx] result := num * srcUnit.factor / dstUnit.factor // 输出结果 fmt.Printf("%v %s Equals %v %s\n", num, srcUnit.name, result, dstUnit.name) }
原代码存在的问题
- 全局变量滥用:
firstUserChoice、secondUserChoice定义为全局变量,跨三个函数修改,很难追踪变量变更来源,增加调试成本 - 硬编码冗余:16种转换组合全部单独写判断,后续新增单位需要新增大量重复代码,容易出现笔误(原代码就存在厘米转毫米输出单位写错、千米转米输出单位写错的bug)
- 函数命名不清晰:
secondStage、thirdStage这类命名无法体现函数实际作用,可读性差 - 输入逻辑不合理:用户输入无效选项后没有重试机制,直接进入下一流程,且if/else分支无论结果如何都会执行下一阶段函数,分支逻辑完全无效
- 常量定义零散:单位名称分散在各个判断分支里,修改单位名需要改多处地方
内容的提问来源于stack exchange,提问作者barfin
相关产品推荐
相关产品推荐

