Golang math 包 Floor 缺失函數體

偶然間,想測測 math 包下的一些函數,發現 math 包中的導出函數沒有函數體,我照着這個代碼,在我自己的 .go 文件中報錯missing function body.

代碼長這樣:

// Trunc returns the integer value of x.
//
// Special cases are:
//    Trunc(±0) = ±0
//    Trunc(±Inf) = ±Inf
//    Trunc(NaN) = NaN
func Trunc(x float64) float64

func trunc(x float64) float64 {
    if x == 0 || IsNaN(x) || IsInf(x, 0) {
        return x
    }
    d, _ := Modf(x)
    return d
}

兩個疑問:

  1. func Trunc(x float64) float64這種寫法是啥東西,哪來的語法,來源是啥
  2. 下面的已經實現了的未導出函數func trunc(x float64) float64 {...} 和這個函數什麼關係

啥東西

首先說明這是啥東西,其實這是一個函數聲明,真正的函數主體是彙編實現的,如果查看源碼,這個函數出自 math 包下的 floor.go 文件,這個文件所在文件夾會有以下這些文件:

floor_386.s
floor_amd64.s
floor_amd64p32.s
floor_arm.s
floor_arm64.s
floor_ppc64x.s
floor_s390x.s
floor_wasm.s

floor.go 中的函數聲明都是在彙編文件內實現的

語法來源是參考 golang spec,原理就是

A function declaration may omit the body. Such a declaration provides the signature for a 》 function implemented outside Go, such as an assembly routine.

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

func flushICache(begin, end uintptr)  // implemented externally

大意就是:函數聲明可以省略正文。這樣的聲明是爲了在 Go 之外實現這個函數提供了簽名,例如彙編程序。

關聯

func trunc(x float64) float64 {...} 有和這個聲明有什麼關係呢?

根據參考鏈接解釋,這是 golang 的一個備用實現,比如 floor_arm.s 中實現 Trunc 的時候反而調用的是 golang 的實現,也可以用作參考和測試。

floor_arm.s

#include "textflag.h"

TEXT ·Floor(SB),NOSPLIT,$0
    B    ·floor(SB)

TEXT ·Ceil(SB),NOSPLIT,$0
    B    ·ceil(SB)

TEXT ·Trunc(SB),NOSPLIT,$0
    B    ·trunc(SB)

這裏的 .trunc 等就是調用的 golang 實現的

參考鏈接:

Bodiless function in Golang

golang spec - function declarations

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章