Golang中println的怪异行为解析

Golang中println的怪异行为解析

n := 43210 // time in seconds
fmt.Println(n/60*60, "hours and", n%60*60, "seconds")

结果:

43200 hours and 600 seconds

我不知道为什么。

6 回复

非常惭愧,我搞错了。

更多关于Golang中println的怪异行为解析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


绝对不是。 对于Java和C语言,它们的工作方式与Go语言相同。

或者你可以这样写

n / (60*60)

在其他语言中,比如 Java 和 C,打印输出是 n/60*60 的结果(即 12)。所以我不明白为什么 Golang 如此不同。这是 Golang 的 bug 吗?

在 Go 语言中,除法和乘法确实具有相同的优先级,因此它们会从左到右进行求值。

虽然我现在无法检查 C 语言的情况,但 Elixir、Erlang 和 Rust 的行为与 Go 相同,它们都会像 (n / 60) * 60 这样读取和求值。

(n / 60) * 60

这是一个典型的整数运算优先级和表达式解析问题。问题不在于println本身,而在于运算顺序。

在Go语言中,算术运算符/*%具有相同的优先级,并且是左结合的。这意味着表达式从左到右依次计算。

问题分析:

n := 43210

// 实际计算顺序:
n/60*60 等价于 (n/60)*60 = (43210/60)*60 = 720*60 = 43200
n%60*60 等价于 (n%60)*60 = (43210%60)*60 = 10*60 = 600

正确的写法应该是:

package main

import "fmt"

func main() {
    n := 43210 // time in seconds
    
    // 方法1:使用括号明确优先级
    fmt.Println(n/(60*60), "hours and", n%(60*60), "seconds")
    
    // 方法2:分步计算
    hours := n / 3600
    seconds := n % 3600
    fmt.Println(hours, "hours and", seconds, "seconds")
}

输出结果:

12 hours and 10 seconds

更完整的示例:

package main

import "fmt"

func main() {
    n := 43210
    
    // 错误的方式 - 运算优先级问题
    fmt.Println("错误结果:")
    fmt.Println(n/60*60, "hours and", n%60*60, "seconds")
    
    // 正确的方式
    fmt.Println("\n正确结果:")
    fmt.Println(n/(60*60), "hours and", n%(60*60), "seconds")
    
    // 详细分解
    totalSeconds := n
    hours := totalSeconds / 3600
    remainingSeconds := totalSeconds % 3600
    minutes := remainingSeconds / 60
    seconds := remainingSeconds % 60
    
    fmt.Printf("\n详细分解: %d小时 %d分钟 %d秒\n", hours, minutes, seconds)
}

问题的本质是运算符优先级和结合性,而不是println函数的怪异行为。在涉及多个相同优先级运算符时,务必使用括号来明确计算顺序。

回到顶部