20210311关于逻辑运算符的执行规则 - ziyouzy/2021blog GitHub Wiki
遇到了一个很好的例子:
river.usr-io808的func (p *USR_IO808) attachRiverNode(riverNodeName string, config rn.Config)bool函数:
for _, riverNode := range p.riverNodes {
if riverNode.Name == riverNodeName {
p.Errors <- NewError(RIVER_USRIO808_INITFAIL, p.UniqueId,
fmt.Sprintf("river-node:%s已被装载与当前river,导致了uid为%s的usr-io8080设备"+
"初始化失败", riverNodeName, p.UniqueId))
return false
}
}
以及river.byteslice的func (p *ByteSlice) attachRiverNode(riverNodeName string, config rn.Config)bool函数
if p.crc_addTail != nil && p.crc_addTail.Name == riverNodeName {
// if p.crc_addTail.Name == riverNodeName { 报错
p.Errors <- NewError(RIVER_BYTESLICEASKER_INITFAIL, p.UniqueId,
fmt.Sprintf("river-node:%s已被装载与当前river,导致了uid为%s"+
"的bytesliceasker设备初始化失败", riverNodeName, p.UniqueId))
return false
}
前者由于for range结构,使得程序会先进行一次数组的range操作,如果内部字段p.riverNodes为空则不会执行循环的内部逻辑,从而避免了调用一个空值的Name()方法
后者由于没有for range的保护于是直接触发了panic
接下来介绍重点,如先进性一次如下书写格式的非空的判断if p.crc_addTail != nil && p.crc_addTail.Name == riverNodeName程序就不会触发panic
因此得出结论虽然上面是一条语句,但是其具备两条语句的特性,如果第一个条件就判定失败则不会进行接下来的操作,一直了解这个很棒的设计,而在这里遇到了最好的实践场景