Suppose there is an internal package that provides a method as follows.
This method is used internally, it has no export properties, so it can’t be imported by other external packages, so since this is the case, is there any way to call this method outside the package? The answer is yes, except that this hack blocks at least 80% of Gopher’s knowledge, and it is go:linkname.
1. go:linkname Basics
Before understanding go:linkname, it is necessary to understand the internal package internal, which is unique to Golang. go 1.4 “Internal” Packages were added in Go 1.14.
An import of a path containing the element “internal” is disallowed if the importing code is outside the tree rooted at the parent of the “internal” directory.
The simple understanding is that this particular internal package can only be imported by a specific external package.
- Package 
/a/b/c/internal/d/e/fcan only be imported by/a/b/c, not by/a/b/d. - Package 
$GOROOT/src/pkg/internal/xxx, can only be imported by$GOROOT/src/. - Package 
$GOROOT/src/pkg/net/http/internalcan only be imported bynet/httpandnet/http/*. - Package 
$GOPATH/src/mypkg/internal/foocan only be imported by$GOPATH/src/mypkg. 
How can I directly reference the internal.print method without violating this principle?
The //go:linkname directive instructs the compiler to use importpath.name as the object file symbolic name of a variable or function declared as localname in the source code. Since this directive can break the type system and package modularity, it is only enabled in files that have unsafe imported. As follows.
This completes the process of go:linkname pointing the method implementation to an unexported method implementation of an external package. In simple terms, this means that go:linkname [local] [target] binds the specific implementation target to the current local method. When run directly, it prompts a missing body error. This is because go build adds the -complete parameter to check for completeness, and apparently this Print method has no body. Therefore, you need to tell the compiler to bypass this restriction by adding the xxx.s file to the calling directory. Finally the whole file directory is as follows.
The output after running is as follows.
2. go:linkname advanced 1: random numbers
Both runtime.fastrand and math.Rand are pseudo-random number generators. But the difference is that runtime.fastrand is in the context of the current goroutine. Therefore, it does not require locking during frequent calls, so its performance is much better than that of `math. Here are the performance tests of both.
The performance data obtained from benchmarking shows that runtime.Rand crushes math/rand in terms of performance.
 | 
 | 
3. go:linkname Advanced 2: Timestamp
time.Now() and runtime.nanotime1() both get timestamps, but time.Now() has underlying calls to runtime.walltime1 and runtime.nanotime to get the timestamp and program runtime respectively. And the latter only needs to get the timestamp separately. Therefore, in some scenarios, such as statistical time consumption, then you can directly get better performance with nanotime1(). The following is the benchmarking code.
As you can see, runtime.nanotime1() crushes time.Now() in terms of performance.
 | 
 | 
4. Summary
With an understanding of how go:linkname works, we can optimize our code for specific scenarios and improve performance bottlenecks. When reading the golang source code, you can also see a lot of go:linkname directives, understanding this directive helps us better understand the underlying logic of golang code.