我注意到,当我编写以下代码时,编译器会生成missing return statement error:

// Similar loops make sense in retry patterns
// but this is just a simple example
func TestMethod() int {
    for i := 0; i < 10; i++ {
        return 0
    }
}

这是当下面的编译没有任何错误:

func TestMethod() int {
    for {
        return 0
    }
}

第一个代码在逻辑上和技术上都很好,因为该方法不可能无法返回.编译器显示该错误有什么原因吗?或者这是某种缺失的逻辑或错误?

推荐答案

将@Cerise Limón的 comments 扩展为一个答案,断言"第一个代码在技术上是正确的"是错误的.

Go language specification says this名:

如果函数的签名声明了结果参数,则为the function body's statement list must end in a terminating statement.

also this:

[terminating statements include] a "for" statement in which:
- there are no "break" statements referring to the "for" statement, and
- the loop condition is absent, and
- the "for" statement does not use a range clause.

(由我补充强调)

判断第一个函数中的代码,我们可以看到规范中的这些条件不满足:

func TestMethod() int {
    for i:= 0; i < 10; i++ {
        return 0
    }
}

该函数有一个RESULT参数(返回值为int),因此必须以终止语句结束,但该函数的最后一条语句是for语句with a condition,这是规范定义的not条"终止语句".

这看起来可能有些奇怪,但实际上在技术上是正确的.

奖励material

那么为什么第二个功能是好的呢?

func TestMethod() int {
    for {
        return 0
    }
}

在本例中,该函数中的最后一个语句是for,no condition,and,no break statement referring to the for loop,满足终止语句的语言规范定义.

这其中有逻辑在起作用.

如果没有条件的for语句包含break,则循环may终止,因此函数需要返回语句.

如果没有条件的for语句not包含break(并且没有return语句),则循环不会终止(至少,不会是需要函数返回值的正常执行路径的结果).

同样值得注意的是,没有控制流分析来确定是否有任何break条语句是可到达的;例如,下面的代码还会触发"未返回"编译错误,即使break显然无法访问:

func foo() int {
    for {
        if false {
            break
        }
        return 0
    }
    // <-- error: missing return
}

Go相关问答推荐

如何复制*C.char?

macOS上GoLand 2023.3.4中的代码导航

难以为多个平台添加Go Bazel构建选项

一种基于时间的Golang函数节制器

按键值排序字符串- Golang

为什么Slices包中的函数定义Slice参数的类型参数?

如何使用gopher-lua定义一个Lua函数,该函数有一个预定义的表作为param,Lua脚本可以在其中访问该函数中的表?

Kafka架构注册表-Broker:Broker无法验证记录

格式化 Azure SDK 的 golang 时间

Go:如何在不加载正文的情况下创建 http 代理通行证

Go 中的 protobuf FieldMask 解组

我应该先解锁然后再广播吗?

在golang中以JSON格式获取xwwwformurlencoded请求的嵌套键值对

Gorm 在自定义字符串类型上返回 scanner 错误

从 eBPF LRU 哈希映射中错误驱逐的元素

使用 Go 解组 SOAP 消息

使用正则表达式拆分具有相同标题的数据块

递归数据 struct 解组在 Go Lang Protobuf 中给出错误无法解析无效的线格式数据

在 Go 中,为什么 exec.Command() 失败但 os.StartProcess() 成功启动winget.exe?

获取单调时间,同 CLOCK_MONOTONIC