go语言魔法技能go:linkname

我们在看Go语言的源码时,经常会看到一些特别的注释,比如:

//go:build
//go:linkname
//go:nosplit
//go:noescape
//go:uintptrescapes
//go:noinline
//go:nowritebarrierrec

等等,这些特别的注释其实是Go编译器的指示指令。这里介绍一下go:linkname指令其及用法,并给出各种用法的完整实例,网上很少有各种用法的完整实例的。

go:linkname的指令格式为:

//go:linkname localname [importpath.name]
  • localname为本包中的名字
  • importpath.name为引入包的路径及其名字,可省略。

在使用该指令前,需要import unsafe包。

该指令写在localname上,但localname可以是importpath.name的别名,也可以是它的实现,即可以是在本包中定义,也可以不是定义。下面就以具体例子来说明:

一、localname函数在本包未实现,相当于是别名

可以看Go源码中time包的runtimeNano函数,如下图:
在这里插入图片描述
runtimeNano函数在此并未实现,只是提供了一个声明,使用//go:linkname runtimeNano runtime.nanotime来告诉编译器该函数使用runtime包中的nanotime函数实现,这里相当于只是一个别名。该函数的定义如下图所示,但是分为nofakefake两种版本:

在这里插入图片描述

在这里插入图片描述

这种用法比较容易理解,定义好一个函数后,可以在其它包中进行多次go:linkname创建别名。

二、localname函数在本包实现

细心的读者应该发现了上图中time_now函数了,即通过//go:linkname time_now time.now指示time包中的now函数使用本包(runtime包)中的time_now函数,当然time包中还是需要有一个now函数的声明,就在前面nanotime函数的上方:

在这里插入图片描述
可以看到now函数上面的注释没有任何编译器指令。

这种用法比较容易出错,很容易出现missing function body错误,这是因为Go在编译时会添加-complete将该包作为一个纯Go包来编译,即该包中不包括非Go组件。
在这里插入图片描述

遇到这种情况,有两种方式解决:

  • 在该包中添加一个空的.s文件,随便取一个名字,比如empty.s
  • 在函数前添加//go:linkname localname格式的指令,注意没有importpath.name

三、实例

新建一个目录demo,使用VSCode打开,其目录结构如下:

$ tree -a
.
├── .vscode
│   ├── launch.json
│   └── tasks.json
├── case3
│   ├── case3.go
│   ├── empty.s
│   └── internal
│       └── priv.go
├── go.mod
├── main.go
├── outer
│   ├── internal
│   │   └── inter.go
│   └── outer.go
├── private
│   └── private.go
└── public└── public.go8 directories, 11 files

在这里插入图片描述

main.go

package mainimport ("demo/outer""demo/public"
)func main() {public.Demo()outer.Outer()
}

go.mod

module demogo 1.22.0

public.go

package publicimport (_ "demo/private"_ "unsafe"
)//go:linkname foo demo/private.foo
func foo()func Demo() {foo()
}

private.go

package privateimport ("fmt"
)func foo() {fmt.Println("Private foo")
}

outer.go

package outerimport (_ "demo/outer/internal"_ "unsafe"
)//go:linkname Outer
func Outer()

inter.go

package internalimport ("fmt"_ "unsafe"
)//go:linkname inter demo/outer.Outer
func inter() {fmt.Println("internal.inter")
}

case3.go

package case3import _ "demo/case3/internal"func Foo()

empty.s是一个空文件,用于告诉编译器,本包不是一个纯Go组件包

priv.go

package internalimport ("fmt"_ "unsafe"
)//go:linkname f demo/case3.Foo
func f() {fmt.Println("internal.f")
}

tasks.json

{"version": "2.0.0","tasks": [{"type": "go","label": "go: build workspace","command": "build","args": ["./..."],"problemMatcher": ["$go"],"group": {"kind": "build","isDefault": true},"detail": "cd d:\\go; go build ./..."}]
}

launch.json

{// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387"version": "0.2.0","configurations": [{"name": "Launch Package","type": "go","request": "launch","mode": "auto","program": "${workspaceFolder}","preLaunchTask": "go: build workspace"}]
}

如果对你有帮助,欢迎点赞收藏!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/710255.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VUE实现Office文档在线编辑,支持doc/docx、xls/xlsx、ppt/pptx、pdf等

1.微软提供的在线Office预览(只能预览,不能编辑) https://view.officeapps.live.com/op/view.aspx?src服务器上文档地址(http开头) 2.国内在线Office方案: 腾讯文档、石墨文档、飞书 优势:跨…

Linux红帽rhce认证多少钱?考个RHCE难不难?

Linux作为开源操作系统的佼佼者,已经广泛应用于各个领域。红帽认证工程师(Red Hat Certified Engineer,简称RHCE)作为Linux领域权威的认证之一,自然成为了众多IT从业者追求的目标。那么,RHCE认证的培训费用是多少?考取这一认证又…

Linux的条件变量

条件变量 条件变量本身不是锁,但是它可以造成线程阻塞。通常于互斥锁配合使用。给多线程提供一个会和的场合。 使用互斥量保护共享数据使用条件变量可以造成线程阻塞,等待某个条件的发生,当条件满足的时候解除阻塞。 条件变量的两个动作&a…

python 基础知识点(蓝桥杯python科目个人复习计划55)

今日复习内容:做题 例题1:体育健将 问题描述: 小蓝作为班级里的体育健将,他被安排在校运会时参加n个体育项目,第i个体育项目参赛需要耗时ai分钟,赛后休息需要bi分钟(这意味着当他参加完这场比…

【AIGC大模型】InstantID 赏析

论文地址:https://arxiv.org/abs/2401.07519 InstantID 主页:https://instantid.github.io/ Demo :https://huggingface.co/spaces/InstantX/InstantID code: InstantID/InstantID: InstantID : Zero-shot Identity-Preserving…

计算机组成原理-第一/二章 概述和数据的表示和运算【期末复习|考研复习】

文章目录 前言第一章 计算机组成原理 概述及各种码1.1 计算机硬件的基本组成1.1.1 存储器1.1.2 运算器1.1.3 控制器 1.2 计算机的工作过程1.3 计算机的性能指标1.4 各个字长区别与联系 第二章 数据的表示与运算2.1 ASCII码2.2 各种码2.3 浮点数 总结 前言 给大家整理了一下计算…

雅特力AT32L021首款低功耗MCU震撼登场

雅特力于2月28日正式发布AT32L021首款入门级低功耗MCU,搭配不同容量Flash、SRAM,提供7种封装类型共21个型号选择,最小封装面积仅3x3mm。为降低能耗,延长设备运作时间,AT32L021系列支持多种能耗模式和休眠模式&#xff…

Mysql Day07

存储过程 -- 存储过程基本语法 -- 创建 create procedure p1() begin select count(*) from student; end; -- 调用 call p1(); -- 查看 select * from information_schema.ROUTINES where ROUTINE_SCHEMA itcast; show create procedure p1; -- 删除 drop procedure if exis…

TCP/UDP模型:2024/2/29

作业1&#xff1a;TCP模型 服务器端&#xff1a; #include <myhead.h> #define SER_IP "192.168.199.129" #define SER_PORT 8899int main(int argc, const char *argv[]) {//1.创建用于连接的套接字文件int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd-1){per…

深入理解nginx的https alpn机制

目录 1. 概述2. alpn协议的简要理解2.1 ssl的握手过程2.2 通过抓包看一下alpn的细节3. nginx源码分析3.1 给ssl上下文设置alpn回调3.2 连接初始化3.3 处理alpn协议回调3.4 握手完成,启用http协议4.4 总结阅读姊妹篇:深入理解nginx的https alpn机制 1. 概述 应用层协议协商(…

基于Siamese网络的zero-shot意图分类

原文地址&#xff1a;Zero-Shot Intent Classification with Siamese Networks 通过零样本意图分类有效定位域外意图 2021 年 9 月 24 日 意图识别是面向目标对话系统的一项重要任务。意图识别(有时也称为意图检测)是使用标签对每个用户话语进行分类的任务&#xff0c;该标签…

网络编程学习

思维导图 代码练习 TCP实现通信 服务器端代码 #include <myhead.h> #define SER_IP "192.168.152.135" #define SER_PORT 8910 int main(int argc, const char *argv[]) {//&#xff11;创建用于监听的套接字int sfd -1;sfd socket(AF_INET,SOCK_STREAM,0)…

【mysql】 1819 - Your password does not satisfy the current policy requirements

创建mysql账户密码时候提示&#xff1a; 1819 - Your password does not satisfy the current policy requirements 1819-您的密码不符合当前策略要求 下面是执行的sql DROP DATABASE IF EXISTS company;CREATE DATABASE company CHARACTER SET utf8mb4 ;grant all on com…

VuePress + GitHub 搭建个人博客踩坑记录

最近想给我教练搭个网站,本来选的是 VuePress 框架,也折腾完了,起码是搭建出来了,踩的坑也都总结好了 但是最近发现了一个更简洁的模板: VuePress-theme-hope ,所以最终网站使用的样式是这个 不过我觉得这里面踩坑的记录应该还是有些价值的,分享出来,看看能不能帮到一些小伙伴~…

2000-2022年上市公司绿色专利申请占比/数据

2000-2022年上市公司绿色专利申请占比数据 1、时间&#xff1a;2000-2022年 2、来源&#xff1a;国家知识产权局、WIPO绿色专利清单 3、指标&#xff1a;年份、股票代码、股票简称、行业代码、省份、城市、区县、行政区划代码、城市代码、区县代码、首次上市年份、上市状态、…

黑马瑞吉外卖练习笔记

day2 员工管理 完善登录 问题&#xff1a;用户不登录&#xff0c;直接访问系统首页&#xff0c;照样可以正常访问。我们希望&#xff0c;只有登录成功后才可以访问系统中的页面&#xff0c;如果没有登录则跳转到登录页面 怎么实现&#xff1f; 用过滤器或拦截器&#xff0c;在…

[数据结构 C++] AVL树的模拟实现

文章目录 1、AVL树1.1 AVL树的概念 2、AVL树节点的定义3、AVL树的插入和旋转3.1 左单旋左旋代码实现 3.2 右单旋右旋代码实现 3.3 右左双旋右左双旋的代码实现 3.4 左右双旋左右双旋的代码实现 3.5 insert接口实现 4、判断是否为AVL树判断AVL树的代码实现 5、AVL树的性能 问题引…

刷题第3天(简单题):LeetCode203--移除链表元素--虚拟头结点

LeetCode203:给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]示例 2&#xff1a;输入…

面试数据库篇(mysql)- 07索引创建原则与失效及优化

索引创建原则 1). 针对于数据量较大,且查询比较频繁的表建立索引。 2). 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。 3). 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。 4). 如果是字符…

flink下载安装部署说明

下载 下载地址 flink-1.16.2下载安装包&#xff0c;flink-1.16.2-bin-scala-2.12.zip资源-CSDN文库 安装 解压目录 启动集群 ./start-cluster.sh 提交作业 ./bin/flink run examples/streaming/WordCount.jar 查看日志 停止集群 ./bin/stop-cluster.sh 开启webui vim c…