如何避免在 switch-case 语句中出现不可达代码?

huangapple go评论70阅读模式
英文:

How to avoid non reachable code with switch-case?

问题

我们有以下代码场景:

func f(a, b, c *int) *int {

    check := c == nil
    switch check {
    case true:
        if g(a) {
            return nil
        }
        return h(a)
    case false:
        return k(a, b, c)
    }
    return nil // 不可达代码
}

return nil 是不可达代码。可复现的代码:https://play.golang.org/p/lIrTxZkNbg6

为什么 Go 编译器会报告不可达代码?如何避免不可达代码?是 switch-case 语法导致了不可达代码吗?

英文:

We have below code scenario:

func f(a, b, c *int) *int {

	check := c == nil
	switch check {
	case true:
		if g(a) {
			return nil
		}
		return h(a)
	case false:
		return k(a, b, c)
	}
	return nil // non reachable code
}

return nil is non-reachable code. Reproducible code: https://play.golang.org/p/lIrTxZkNbg6

Why Go compiler complains about non-reachable code? How to avoid non-reachable code? Is switch-case syntax causing non-reachable code?

答案1

得分: 2

请将您的函数用更简单的方式重写(使用if语句)。

func f(a, b, c *int) *int {
	if c == nil {
		if g(a) {
			return nil
		}
		return h(a)
	} else {
		return k(a, b, c)
	}
}

重写后的函数使用了嵌套的if语句来处理不同的情况。首先,它检查指针c是否为nil。如果是,它会进一步检查函数g(a)的返回值。如果g(a)返回true,则返回nil;否则,返回h(a)的结果。如果c不为nil,则直接调用k(a, b, c)并返回其结果。

英文:

rewrite your function in more simple terms (using if).

func f(a, b, c *int) *int {

		if c == nil {
			if g(a) {
				return nil
			}
			return h(a)
		}
		
		return k(a, b, c)
}

答案2

得分: 2

你的 switch 语句评估的是一个只有两个可能选择的布尔值,所以它永远不可能达到最后的返回语句。
在这种特定情况下,使用 if 语句比 switch 更易读。

if check {
    if g(a) {
        return nil
    }
    return h(a)
}
return k(a, b, c)
英文:

Your switch statement is evaluating a boolean which has just 2 possible choices, so there is no possibility for it to ever reach the final return statement.
In this specific case it is more readable to use if instead of switch

if check {
    if g(a) {
        return nil
    }
    return h(a)
}
return k(a, b, c)

答案3

得分: 1

编译器只有在跟随一个终止语句后才知道该语句是不可达的。终止的switch语句包括:

  • 在switch语句中没有引用该switch语句的break语句,
  • 存在一个默认情况,
  • 每个case语句列表(包括默认情况)以终止语句或可能带标签的"fallthrough"语句结尾。

因此,规则不足以确定在每个可能的值都有终止情况的情况下(就像你这里的情况),该语句是不可达的。这个规则会给编译器和语言增加不必要的复杂性,因为实际上它只适用于你所展示的这种特定情况,而这种情况可以(而且应该)很容易地用if/else语句替代。

请记住,switch语句中的case值不一定需要是常量或唯一的,而且bool可能是唯一一个具有足够少的唯一值,以至于您可能真实地在switch语句中涵盖所有这些值。

英文:

The compiler only knows that the statement is unreachable if it follows a terminating statement. Terminating switch statements are:

> A "switch" statement in which:
> - there are no "break" statements referring to the "switch" statement,
> - there is a default case, and
> - the statement lists in each case, including the default, end in a terminating statement, or a possibly labeled "fallthrough" statement.

So, the rules aren't comprehensive enough to determine this case where every possible value of the switched data type has a terminating case (as you have here). This rule would add needless complexity to the compiler and language as, practically, it would only apply to the exact situation you've shown here, which can (and should) easily be replaced by if/else statements.

Keep in mind that case values in a switch statement don't necessarily need to be constant or unique, and bool is arguably the only data type that has few enough unique values that you might realistically cover all of them in a switch statement.

huangapple
  • 本文由 发表于 2021年8月11日 20:06:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/68741717.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定