我在Go中遇到了一个编写程序的奇怪错误。
基本上,我有一个switch语句,每个case应该调用一个函数,setill,两次。但是当相关案例运行时,它只调用一次函数。
以下是代码段:
check := true
n, e, s, w := b.North, b.East, b.South, b.West
switch {
// NE (>)
case n.Closed && e.Closed:
check = check && p.setIll(s)
check = check && p.setIll(w)
// NS (\\)
case n.Closed && s.Closed:
check = check && p.setIll(e)
check = check && p.setIll(w)
// NW (^)
case n.Closed && w.Closed:
check = check && p.setIll(e)
check = check && p.setIll(s)
// ES (v)
case e.Closed && s.Closed:
check = check && p.setIll(n)
check = check && p.setIll(w)
// EW (//)
case e.Closed && w.Closed:
fmt.Println("Running setIll the first time")
check = check && p.setIll(n)
fmt.Println("Running it again")
check = check && p.setIll(s)
fmt.Println("And now we're done running")
// SW (<)
case s.Closed && w.Closed:
check = check && p.setIll(n)
check = check && p.setIll(e)
}
这里的setIll:
func (p Player) setIll(n *Node) bool {
fmt.Println("I'm running!")
p.Illegal.Nodes[n.Loc.X][n.Loc.Y].Closed = true
return !p.Forced.Nodes[n.Loc.X][n.Loc.Y].Closed
}
这会产生以下输出:
Running setIll the first time
I'm running!
Running it again
And now we're done running
请注意&#34;我正在跑步!&#34;仅在输出中出现一次。知道为什么会这样吗?
答案 0 :(得分:3)
不是switch
绊倒你,&&
的工作方式。
&&
和||
是short-circuiting运营商:如果左侧结果足够,他们根本不会执行右侧的操作确定答案是什么。如果您的表达式为a && f()
且a
为false
,则无需运行f()
即可查看最终结果false
。 Go规范的方式是"The right operand is evaluated conditionally."
这在很多语言中都很常见。当您的第一次检查必须通过它才有意义来运行其他检查时,这会很有帮助。例如,假设您要检查Web应用程序中的用户权限,但仅当用户完全登录(user != nil
)时:user != nil && user.HasPermission(requiredPerm)
执行您所需的操作。
如果您想以与现在相同的方式设置check
var,但是setIll
总是被调用两次,您可以将setIll
结果分配给变量在任何&&
表达式之外:
ck1, ck2 := p.setIll(n), p.setIll(s)
check = check && ck1 && ck2