package a
func test() {
println("this is a/test()")
}
type A struct {
Name string
}
func (*A) test1() {
println("this is a/(*A).test1()")
}
func (A) test2() {
println("this is a/A.test2()")
}
func (a *A) setName(name string) {
a.Name = name
}
func (a *A) getName() string {
return a.Name
}
package b
import (
"gitlab.meitu.com/mtgo/fw/fortest/a"
_ "unsafe" // linkname require unsafe
)
//go:linkname Test gitlab.meitu.com/mtgo/fw/fortest/a.test
func Test()
// 指针接收器
//go:linkname Test1 gitlab.meitu.com/mtgo/fw/fortest/a.(*A).test1
func Test1(_ *a.A)
// 非指针接收器
//go:linkname Test2 gitlab.meitu.com/mtgo/fw/fortest/a.A.test2
func Test2(_ a.A)
//go:linkname GetName gitlab.meitu.com/mtgo/fw/fortest/a.(*A).getName
func GetName(_ *a.A) string
//go:linkname SetName gitlab.meitu.com/mtgo/fw/fortest/a.(*A).setName
func SetName(_ *a.A, name string)
package main
import (
"fmt"
"gitlab.meitu.com/mtgo/fw/fortest/a"
"gitlab.meitu.com/mtgo/fw/fortest/b"
)
func main() {
b.Test()
var v a.A
b.Test1(&v)
b.Test2(v)
b.SetName(&v, "robin")
fmt.Println(b.GetName(&v))
}
/*
output:
this is a/test()
this is a/(*A).test1()
this is a/A.test2()
robin
*/
需要注意的是,在b包的目录下需要放个.s后缀的文件,原因在于Go在编译的时候会启用-complete编译器flag,它要求所有的函数必需包含函数体。创建一个空的汇编语言文件绕过这个限制。
附:有局限的小玩意,见 https://github.com/alangpierce/go-forceexport
近期评论