在 Go 中用数字范围编写多个嵌套的 if-else 的简洁方法
Clean way of writing several nested if-else with number ranges in Go
这段代码是有效的,但是我看的时候感觉不太好。我发现重构为更清晰或更简短的内容时遇到了麻烦。将代码分成几个 if-return 在这里似乎没有太大帮助。提示?谢谢!
if t < 0 {
r = 0
} else if t >= 0 && t < 7.5 {
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 2
}
} else if t >= 7.5 && t < 10 {
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 4
}
} else if t >= 10 && t < 20 {
if m >= 0 && m < 0.125 {
r = 1
} else if m >= 0.125 && m < 0.25 {
r = 3
} else {
r = 4
}
} else if t >= 20 && t < 22.5 {
if m >= 0 && m < 0.125 {
r = 7
} else if m >= 0.125 && m < 0.375 {
r = 3
} else {
r = 4
}
} else if t >= 22.5 && t < 27.5 {
if m >= 0 && m < 0.125 {
r = 7
} else if m >= 0.125 && m < 0.625 {
r = 5
} else {
r = 6
}
} else if t >= 27.5 {
if m >= 0 && m < 0.25 {
r = 7
} else if m >= 0.25 && m < 0.625 {
r = 5
} else {
r = 6
}
}
简化外层if/else if/else去除冗余比较并转换为switch:
switch {
case t < 0:
r = 0
case t < 7.5:
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 2
}
case t < 10:
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 4
}
case t < 20:
if m >= 0 && m < 0.125 {
r = 1
} else if m >= 0.125 && m < 0.25 {
r = 3
} else {
r = 4
}
case t < 22.5:
if m >= 0 && m < 0.125 {
r = 7
} else if m >= 0.125 && m < 0.375 {
r = 3
} else {
r = 4
}
case t < 27.5:
if m >= 0 && m < 0.125 {
r = 7
} else if m >= 0.125 && m < 0.625 {
r = 5
} else {
r = 6
}
default:
if m >= 0 && m < 0.25 {
r = 7
} else if m >= 0.25 && m < 0.625 {
r = 5
} else {
r = 6
}
}
可以对内部语句进行类似的修改。代码:
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 2
}
变为:
switch {
case m < 0:
// r not changed
case m < 0.125:
r = 1
default:
r = 2
}
查看这些值,您可以使用一些数据结构对范围检查进行编码:
type Rng struct {
From,To float64
V int
}
func (r Rng) In(val float64) bool { return val>=r.From && val<r.To }
type ARange struct {
T Rng
M []Rng
Def int // Default value for r if none of the M ranges match
}
var ranges=[]ARange{ {T:Rng{0,7.5}, M:[]Rng{ {0,0.125,1} }, Def: 2 },
...
然后,编写遍历 ranges
的每个元素并检查 t
和 m
以查看是否有任何匹配项的 for 循环。
这段代码是有效的,但是我看的时候感觉不太好。我发现重构为更清晰或更简短的内容时遇到了麻烦。将代码分成几个 if-return 在这里似乎没有太大帮助。提示?谢谢!
if t < 0 {
r = 0
} else if t >= 0 && t < 7.5 {
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 2
}
} else if t >= 7.5 && t < 10 {
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 4
}
} else if t >= 10 && t < 20 {
if m >= 0 && m < 0.125 {
r = 1
} else if m >= 0.125 && m < 0.25 {
r = 3
} else {
r = 4
}
} else if t >= 20 && t < 22.5 {
if m >= 0 && m < 0.125 {
r = 7
} else if m >= 0.125 && m < 0.375 {
r = 3
} else {
r = 4
}
} else if t >= 22.5 && t < 27.5 {
if m >= 0 && m < 0.125 {
r = 7
} else if m >= 0.125 && m < 0.625 {
r = 5
} else {
r = 6
}
} else if t >= 27.5 {
if m >= 0 && m < 0.25 {
r = 7
} else if m >= 0.25 && m < 0.625 {
r = 5
} else {
r = 6
}
}
简化外层if/else if/else去除冗余比较并转换为switch:
switch {
case t < 0:
r = 0
case t < 7.5:
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 2
}
case t < 10:
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 4
}
case t < 20:
if m >= 0 && m < 0.125 {
r = 1
} else if m >= 0.125 && m < 0.25 {
r = 3
} else {
r = 4
}
case t < 22.5:
if m >= 0 && m < 0.125 {
r = 7
} else if m >= 0.125 && m < 0.375 {
r = 3
} else {
r = 4
}
case t < 27.5:
if m >= 0 && m < 0.125 {
r = 7
} else if m >= 0.125 && m < 0.625 {
r = 5
} else {
r = 6
}
default:
if m >= 0 && m < 0.25 {
r = 7
} else if m >= 0.25 && m < 0.625 {
r = 5
} else {
r = 6
}
}
可以对内部语句进行类似的修改。代码:
if m >= 0 && m < 0.125 {
r = 1
} else {
r = 2
}
变为:
switch {
case m < 0:
// r not changed
case m < 0.125:
r = 1
default:
r = 2
}
查看这些值,您可以使用一些数据结构对范围检查进行编码:
type Rng struct {
From,To float64
V int
}
func (r Rng) In(val float64) bool { return val>=r.From && val<r.To }
type ARange struct {
T Rng
M []Rng
Def int // Default value for r if none of the M ranges match
}
var ranges=[]ARange{ {T:Rng{0,7.5}, M:[]Rng{ {0,0.125,1} }, Def: 2 },
...
然后,编写遍历 ranges
的每个元素并检查 t
和 m
以查看是否有任何匹配项的 for 循环。