Golang多个if 优化与代码健壮性小技巧

没优化之前: 嵌套if, 检查是否有中文字段值, 否则去查找英文值, 都没有则返回默认值

go 复制代码
if record.City.Names["zh-CN"] == "" {
	city = record.City.Names["en"]
	if record.City.Names["en"] == "" {
		city = record.City.Names["en"]
	}
} else {
	city = "未知地域"
}

优化后: 平级if...else代替嵌套if

go 复制代码
if name, ok := record.City.Names["zh-CN"]; ok {
	city = name
} else if city, ok = record.City.Names["en"]; ok {
	city = record.City.Names["en"]
} else {
	city = "未知地域"
}

知识点: 利用go的ok模式,对查询map对象的值是否存在更加简洁和安全

更进一步的优化, 去掉else

这对else的处理逻辑有明确的值时非常有用

go 复制代码
city = "未知地域"
if name, ok := record.City.Names["zh-CN"]; ok {
	city = name
} else if name, ok = record.City.Names["en"]; ok {
	city = name
}

使用switch代替多个if分支: 根据成绩的分数段给出对应的等级

go 复制代码
func calculateGrade(score int) string {
	var grade string

	if score >= 90 && score <= 100 {
		grade = "A"
	} else if score >= 80 && score < 90 {
		grade = "B"
	} else if score >= 70 && score < 80 {
		grade = "C"
	} else if score >= 60 && score < 70 {
		grade = "D"
	} else if score >= 0 && score < 60 {
		grade = "F"
	} else {
		grade = "Invalid Score"
	}

	return grade
}

优化后: 使代码更加简洁,并且避免了多个嵌套的 if-else 语句。同时,使用 switch 语句还能够处理默认情况,即当 score 不满足任何一个分支条件时,默认返回 "Invalid Score"

go 复制代码
func calculateGrade(score int) string {
	var grade string

	switch {
	case score >= 90 && score <= 100:
		grade = "A"
	case score >= 80 && score < 90:
		grade = "B"
	case score >= 70 && score < 80:
		grade = "C"
	case score >= 60 && score < 70:
		grade = "D"
	case score >= 0 && score < 60:
		grade = "F"
	default:
		grade = "Invalid Score"
	}

	return grade
}

错误检查

首先看etcdgithub官网的错误处理例子:

go 复制代码
resp, err := cli.Put(ctx, "", "")
if err != nil {
	switch err {
	case context.Canceled:
		log.Fatalf("ctx is canceled by another routine: %v", err)
	case context.DeadlineExceeded:
		log.Fatalf("ctx is attached with a deadline is exceeded: %v", err)
	case rpctypes.ErrEmptyKey:
		log.Fatalf("client-side error: %v", err)
	default:
		log.Fatalf("bad cluster endpoints, which are not etcd servers: %v", err)
	}
}

我们可以进一步优化, 使用go自带的包errors对错误类型进行更加健壮的检查, 但是对开发者的要求较高, 需要预定义正确的错误类型, 来保证正确的比较错误

go 复制代码
resp, err := cli.Put(ctx, "", "")
if err2 != nil {
		switch {
		case errors.Is(err, context.Canceled):
			log.Fatalf("ctx is canceled by another routine: %v", err)
		case errors.Is(err, context.DeadlineExceeded):
			log.Fatalf("ctx is attached with a deadline is exceeded: %v", err)
		case errors.Is(err, rpctypes.ErrEmptyKey):
			log.Fatalf("client-side error: %v", err)
		default:
			log.Fatalf("bad cluster endpoints, which are not etcd servers: %v", err)
		}
	}
相关推荐
星辰徐哥4 小时前
Spring Boot 微服务架构设计与实现
spring boot·后端·微服务
星辰徐哥4 小时前
Spring Boot 数据导入导出与报表生成
spring boot·后端·ui
明夜之约4 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee4 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Micro麦可乐4 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
Jinkxs4 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
毕设源码_郑学姐4 小时前
计算机毕业设计springboot网络相册设计与实现 基于Spring Boot框架的在线相册管理系统开发与应用 Spring Boot驱动的网络影集设计与实践
spring boot·后端·课程设计
辣机小司4 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录
码农阿豪4 小时前
从零到一:Spring Boot快速接入金仓数据库实战
数据库·spring boot·后端
追逐时光者4 小时前
一个基于 .NET 与 Avalonia 构建、面向 TrinityCore 的开源 WoW 数据库编辑器
后端·.net