如果没有无法访问的返回语句,Go代码将无法编译

时间:2012-11-22 15:45:33

标签: go

以下是在Go中找到数字的阶乘的程序:

func factorial(x uint) uint {
    if x == 0 {
        return 1
    }

    return x * (factorial(x - 1))
}

在输入5上调用此函数的输出为120.但是,如果我添加else语句,则会出错。

func factorial(x uint) uint {
    if x == 0 {
        return 1
    } else {
        return x * (factorial(x - 1))
    }
}

错误:function ends without a return statement

我在最后添加了return

func factorial(x uint) uint {
    if x == 0 {
        return 1
    } else {
        return x * (factorial(x - 1))
    }
    fmt.Println("this never executes")
    return 1
}

然后我回到120的预期输出。

为什么第二种情况会导致错误?为什么在第三种情况下即使函数永远不会到达最后return 1,它还会计算正确的输出?

1 个答案:

答案 0 :(得分:22)

这是众所周知的编译器问题。

甚至还记录了一个问题:http://code.google.com/p/go/issues/detail?id=65

用Go语言的一位作者的话来说:

  

编译器要求返回或恐慌是词法最后的   在具有结果的函数中。这条规则比要求完整更容易   流量控制分析,以确定功能是否到达终点   没有返回(一般来说非常难),而且比简单   列举诸如此类的简单案例的规则。而且,纯粹   词汇,由于价值的变化,错误不会自发产生   例如函数内控制结构中使用的常量。

     

-Rob

从另一条评论in golang-nuts,我们可以推断它不会很快被“修复”:

  

这不是一个错误,这是一个刻意的设计决定。

     

-Rob

请注意,其他语言(如Java)具有允许此else的规则。


2013年3月编辑 - 只是got changed in Go1.1

  

在Go 1.1之前,返回值的函数需要显式   在函数结束时“返回”或调用恐慌;这是一个   简单的方法,使程序员明确的意义   功能。但在很多情况下,最终的“回归”显而易见   不必要的,例如只有无限“for”循环的函数。

     

在Go 1.1中,关于最终“返回”语句的规则更多   宽容。它引入了终止语句的概念,a   保证是函数执行的最后一个语句。   例子包括没有条件的“for”循环和“if-else”   每个半部以“回归”结束的陈述。如果是最终的   函数的语句可以在语法上显示为终止   声明,不需要最终的“返回”声明。

     

请注意,该规则纯粹是语法规则:它不关注   代码中的值,因此不需要复杂的分析。

     

更新:此更改是向后兼容的,但现有代码包含   可以简化多余的“返回”陈述和恐慌   手动。这样的代码可以通过go vet识别。

我提到的问题现已关闭状态“已修复”