以下是在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
,它还会计算正确的输出?
答案 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识别。
我提到的问题现已关闭状态“已修复”。