在go语言的源码中,会发现不少,代码只有函数签名,却看不到函数体,如:vim
// src/os/proc.go 68行 func runtime_beforeExit() // implemented in runtime
此处咱们只看到函数签名,却看不到函数体,全局搜了一把,发现它的函数体却定义在src/runtime/proc.go中微信
// os_beforeExit is called from os.Exit(0). //go:linkname os_beforeExit os.runtime_beforeExit func os_beforeExit() { if raceenabled { racefini() } }
它是经过go:linkname把函数签名和函数体链接在一块儿的。那么咱们在代码中,能够这样实现么?既然库函数中,能够这么用,那咱们本身的代码结构中是不也能够这么用?如下经过实验的方式,一步一步的实现这样的用法
建立项目目录函数
$mkdir demo && cd demo
go mod初始化项目目录测试
$go mod init demo
建立函数签名pkg和函数体pkgspa
$mkdir hello $mkdir link
编写测试代码code
$cd hello // 函数签名 $vim hello.go package hello import ( _ "demo/link" ) func Hello() // 函数体 $vim link.go package link import _ "unsafe" //go:linkname helloWorld demo/hello.Hello func helloWorld() { println("hello world!") }
执行代码图片
$cd demo vim demo.go package main import ( "demo/hello" ) func main() { hello.Hello() }
编译运行源码
go run demo.go # demo/hello hello/hello.go:7:6: missing function body
在hello文件夹下添加aa.s的汇编文件标示,即可以经过编译执行it
$cd hello && touch aa.s $go run demo.go hello world!
喜欢请关注微信公众号“云端漫记" 持续为你更新io