为什么 Go 没有计算整数绝对值的函数?

Why doesn't Go have a function to calculate the absolute value of integers?

为什么Go语言中没有直接计算整数数据类型的绝对值的函数?目前,所有整数值都必须类型转换为 float64,然后传递给 math.Abs(),其中 returns 一个 float64,它再次必须类型转换为整数。

此代码引发 ./prog.go:12:39: cannot use x (type int64) as type float64 in argument to math.Abs 错误,因为 Go 是一种静态类型语言,因此它不允许不同的数据类型:

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println("Hello, playground")
    var x int64 = -10
    
    fmt.Println("Abolute value ", math.Abs(x))  
}

From Go's FAQ,

The standard library's purpose is to support the runtime, connect to the operating system, and provide key functionality that many Go programs require, such as formatted I/O and networking. It also contains elements important for web programming, including cryptography and support for standards like HTTP, JSON, and XML.

There is no clear criterion that defines what is included because for a long time, this was the only Go library. There are criteria that define what gets added today, however.

New additions to the standard library are rare and the bar for inclusion is high. Code included in the standard library bears a large ongoing maintenance cost (often borne by those other than the original author), is subject to the Go 1 compatibility promise (blocking fixes to any flaws in the API), and is subject to the Go release schedule, preventing bug fixes from being available to users quickly.

Most new code should live outside of the standard library and be accessible via the go tool's go get command. Such code can have its own maintainers, release cycle, and compatibility guarantees. Users can find packages and read their documentation at godoc.org.

为了响应创建数学包的浮点函数的整数版本是多么容易,Go 团队成员 Russ Cox once quipped

Ceil, Floor, and Trunc are even easier!

一个合理的解释是,由于这个函数写起来很简单(如果 x < 0,x = -x),它不符合包含的标准。与 float version 比较:

func Abs(x float64) float64 {
    return Float64frombits(Float64bits(x) &^ (1 << 63))
}

虽然有用但并不明显,这是将其包含在标准库中的一个令人信服的理由。

虽然没有标准功能,但你总是可以自己写或者使用第三方解决方案。 This package 包含 Abs 所有内置有符号整数类型的函数。用法(在 go get 之后):

import (
    "fmt"
    "github.com/adam-lavrik/go-imath/i64" // Functions for i64 type
)
...
x := int64(-2)
fmt.Println(i64.Abs(x)) // Output: 2
x = i64.Minimal // Minimal negative value of int64, has no positive pair
fmt.Println(i64.Absu(x)) // Output: 9223372036854775808 (result is converted to uint64)

绝对值只是绝对差值的一种特例[1],其中 第二个值为零。这是整数的绝对值函数,以及 整数的绝对差分函数。奖金是绝对差额 无符号整数函数:

package math

func absInt(x int) int {
   return absDiffInt(x, 0)
}

func absDiffInt(x, y int) int {
   if x < y {
      return y - x
   }
   return x - y
}

func absDiffUint(x, y uint) uint {
   if x < y {
      return y - x
   }
   return x - y
}
  1. https://wikipedia.org/wiki/Absolute_difference