惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
博客园 - 叶小钗
S
SegmentFault 最新的问题
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
L
Lohrmann on Cybersecurity
量子位
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
J
Java Code Geeks
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园 - 三生石上(FineUI控件)
Attack and Defense Labs
Attack and Defense Labs
AI
AI
The Cloudflare Blog
T
Tailwind CSS Blog
S
Schneier on Security
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
Stack Overflow Blog
Stack Overflow Blog
S
Secure Thoughts
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
The Exploit Database - CXSecurity.com
博客园 - 【当耐特】
V2EX - 技术
V2EX - 技术
S
Securelist
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
Help Net Security
Help Net Security
C
Cisco Blogs
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
B
Blog RSS Feed
K
Kaspersky official blog
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Simon Willison's Weblog
Simon Willison's Weblog

Dizzy zone

Pangolin Private Resources With Domain Https About Redis is fast - I'll cache in Postgres n8n and large files Malicious Node install script on Google search Wrapping Go errors with caller info BLAKE2b performance on Apple Silicon State of my Homelab 2025 My homelabs power consumption On Umami ML for related posts on Hugo Probabilistic Early Expiration in Go SQLC & dynamic queries Enums in Go Streaming Netdata metrics from TrueNAS SCALE SQL string constant gotcha Moving from Jenkins to Drone My new server: MSI Cubi 3 Silent My thoughts on Ansible® Profiling gin with pprof How I host this blog, CI and tooling OAuth with Gin and Goth I made my own commenting server. Here's why. Why I hate OpenApi(swagger) IDE for GO Jenkins on raspberry pi 3 How I started my professional career Kestrel vs Gin vs Iris vs Express vs Fasthttp on EC2 nano Go's defer statement Self-hosted disqus alternative for 5$ a month Why I like go Speeding hexo (or any page) for PageSpeed insights Starting a blog with hexo and AWS S3
Refactoring Go switch statements
Vik · 2018-07-28 · via Dizzy zone

When writing Go code, I often end up with lots of enums that I use to fork my logic in a switch statement. Take this enum:

type MyEnum int

const (
	One   MyEnum = iota
	Two   MyEnum = iota
	Three MyEnum = iota
	Four  MyEnum = iota
	Five  MyEnum = iota
)

}

I’ll then end up with a switch in a part of my code, like so

switch myEnum {
	case One:
		err := DoSomeOtherStuff()
		if err != nil {
			return err
		}
	case Two:
		err := DoSomeMagicalStuff()
		if err != nil {
			return err
		}
	case Three:
		err := DoSomeExoticStuff()
		if err != nil {
			return err
		}
	case Four:
		err := DoSomeOtherStuff()
		if err != nil {
			return err
		}
	case Five:
		err := DoSomeStuff()
		if err != nil {
			return err
		}
}

}

When the enums are small, with only a few entries in them, this is all rather nice and readable. But take an enum that’s 10, 20, 100 entries long and a switch becomes way too long. The approach I prefer to take in these cases is construct a map containing all the required functions associated with the enum value as the key for the map.

var myMap = map[MyEnum]func() error{
	One:   DoSomeOtherStuff,
	Two:   DoSomeMagicalStuff,
	Three: DoSomeExoticStuff,
	Four:  DoSomeOtherStuff,
	Five:  DoSomeStuff,
}

}

The switch then can be gotten rid of. Instead, it becomes a map lookup:

if myFunc, ok := myMap[myEnum]; ok {
	err := myFunc()
	if err != nil {
		return err
	}
} else {
    // the default case would go here
}

}

This allows for more concise code and easier extension in the future. However, I do not use this everywhere either. If the enum is small and not going to change often(famous last words) I’ll leave the switch in its place. It does not work in places where you have functions with very different signatures for each of the switch cases either.

EDIT: Handling all the errors

As Jonathan Gold states in the comments below, you can also handle all the errors at once, so the initial switch becomes something along the lines of:

var err error
switch myEnum {
	case One:
		err = DoSomeOtherStuff()
	case Two:
		err = DoSomeMagicalStuff()
	case Three:
		err = DoSomeExoticStuff()
	case Four:
		err = DoSomeOtherStuff()
	case Five:
		err = DoSomeStuff()
}
if err != nil {
	return err
}

}

Thanks, Jonathan.

How do you approach your switches? What other tricks do you use? Let me know in the comments below.