5.cgo 原理解析及优化实践
cgo 工作机制 第二部分 Foreign Function Interface 函数调用 数据交互 抽象模型 1 2 3 对 PC 寄存器的修改 编译器完成地址指引 函数调用规约 Go 1.17 数据结构/类型 内存对象生命周期 GMP cgo 编译的两个阶段 cgo 预编译 常规编译 1 2 生成 wrapper 代码 屏蔽 GMP0 码力 | 45 页 | 5.74 MB | 1 年前3Go 入门指南(The way to Go)
本地代码,但编译后的程序不能够使用 gcc 进行链接。 编译器目前支持以下基于 Intel 或 AMD 处理器架构的程序构建。 图2.1 gc 编译器支持的处理器架构 当你第一次看到这套命名系统的时候你会觉得很奇葩,不过这些命名都是来自于 Plan 9 项目。 g = 编译器:将源代码编译为项目代码(程序文本) l = 链接器:将项目代码链接到可执行的二进制文件(机器代码) (相关的 C 编译器名称为 // #include// #include import "C" 名称 "C" 并不属于标准库的一部分,这只是 cgo 集成的一个特殊名称用于引用 C 的命名空间。在这个命 Go入门指南 - 27 - 本文档使用 看云 构建 名空间里所包含的 C 类型都可以被使用,例如 C.uint 、 C.long 等等,还有 libc 中的函数 C.random() world") } 4.2.1 包的概念、导入与可见性 包是结构化代码的一种方式:每个程序都由包(通常简称为 pkg)的概念组成,可以使用自身的包或者从 其它包中导入内容。 如同其它一些编程语言中的类库或命名空间的概念,每个 Go 文件都属于且仅属于一个包。一个包可以由 许多以 .go 为扩展名的源文件组成,因此文件名和包名一般来说都是不相同的。 你必须在源文件中非注释的第一行指明这个文件属于哪个包,如: 0 码力 | 380 页 | 2.97 MB | 1 年前3Go 入门指南(The way to Go)
处理器架构的程序构建。 2.1 平台与架构 2.1 平台与架构 - 25 - 本文档使用 书栈(BookStack.CN) 构建 图2.1 gc 编译器支持的处理器架构 当你第一次看到这套命名系统的时候你会觉得很奇葩,不过这些命名都是来自于 Plan 9 项目。 1. g = 编译器:将源代码编译为项目代码(程序文本) 2. l = 链接器:将项目代码链接到可执行的二进制文件(机器代码) (相关的2. // #include 3. import "C" 名称 “C” 并不属于标准库的一部分,这只是 cgo 集成的一个特殊名称用于引用 C 的命名空间。在这个命名空间里 所包含的 C 类型都可以被使用,例如 C.uint 、 C.long 等等,还有 libc 中的函数 C.random() 等也可以 被调用。 当你想要使用某个类型作为 Println("hello, world") 7. } 包是结构化代码的一种方式:每个程序都由包(通常简称为 pkg)的概念组成,可以使用自身的包或者从其它包中导 入内容。 如同其它一些编程语言中的类库或命名空间的概念,每个 Go 文件都属于且仅属于一个包。一个包可以由许多以 .go 为扩展名的源文件组成,因此文件名和包名一般来说都是不相同的。 你必须在源文件中非注释的第一行指明这个文件属于哪个包,如: 0 码力 | 466 页 | 4.44 MB | 1 年前3GoFrame框架介绍及设计
单包职责过大,维护成本高 • 包命名困难,易出现重复包名, 使用困惑,开发效率低 • 包管理困难,容易出现 cycle import 循环引用问题 改进: • 代码分层设计,降低代码耦合 • 功能逻辑按照对象封装,细化封 装粒度,降低单包职责 • 规避了同名包名的问题 • 规避了 cycle import 问题 常见项目架构示例2 常见项目架构示例1 对象封装改进 对象封装设计-资源命名规范 在三层架构设计模式下,我们的业务包命名 在三层架构设计模式下,我们的业务包命名 仅会有 api、dao、model、service四个包。 每个业务包仅对外暴露 实例化的对象 用于 该业务领域的具体功能逻辑封装,同一层级 下不同的业务领域逻辑通过不同文件来分别 管理。 包对外的公开对象采用 业务领域名称 来命 名,包内部的数据结构定义采用 业务领域名 称+分层名称 来命名。 对象封装设计-对象封装示例1 api访问service层对象 api访问service层对象 访问service层对象具体操作 对象封装设计-对象封装示例2 路由注册时访问api对象 路由注册具体业务领域对象的方法 对象封装设计-对象封装示例3 model数据结构命名 service调用dao对象示例 对象封装设计-对象访问安全 各分层中的封装对象都是以“可变变量”的形式对外暴露使用,存在被修改的安全风险。 DAO封装设计 第六部分 DAO封装设计-痛点举例0 码力 | 37 页 | 8.84 MB | 1 年前3Golang 入门笔记
通常在堆上分配, 当没有任何变化引用这个地址时,该地址的数据空间就成为一个垃圾,由 GC 来回收 标识符概念 概念 Golang 堆各种变量,方法,函数等命名使用的字符序列成为标识符 凡是自己可以起名的地方都叫做标识符 标识符命名规则 1. 由 26 个英文字母大小写,0-9, _ 组成 2. 数字不可以开头 3. Golang 中严格区分大小写 4. 标识符不能包含空格 5. int //ok 不推荐使用 float32 //ok 不推荐使用 _ //error Abc // ok 标识符命名注意事项 1. 包名,保持package的名字和目录的名字保持一直,尽量采用有意义的包名,简短,有意义,不要和标准库冲突 1. 2. 变量名,函数名,常量名,采用驼峰命名 3. 如果变量名、函数名、长两名首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包内使用 (注意0 码力 | 2 页 | 511.29 KB | 1 年前3Go Web编程
这个才是人生最大的快乐。 这本书目前我放在Github上,我现在基本每天晚上抽空会写一些,时间有限、能力有限,所以希望更多的朋友参与到 这个开源项目中来。 撰写方法 撰写方法 文件命名 文件命名 每个章节建立一个md文件,如第11章的第3节,则建立11.3.md 11.3.md。 代码文件 代码文件 代码文件置于src目录之下。每小节代码按目录存放。如第11章的第3节的代码保存于src/11 夹名不 同。默认生成的可执行文件名是文件夹名。) go build会忽略目录下以“_”或“.”开头的go文件。 如果你的源代码针对不同的操作系统需要不同的处理,那么你可以根据不同的操作系统后缀来命名文件。例 如有一个读取数组的程序,它对于不同的操作系统可能有如下几个源文件: arraylinux.go arraydarwin.go arraywindows.go arrayfreebsd.go go build的时候会选择性地编译以系统名结尾的文件(linux、darwin、windows、freebsd)。例如Linux系 统下面编译只会选择array_linux.go文件,其它系统命名后缀文件全部忽略。 go clean go clean 这个命令是用来移除当前源码包里面编译生成的文件。这些文件包括 _obj/ 旧的object目录,由Makefiles遗留0 码力 | 295 页 | 5.91 MB | 1 年前3Go基础语法宝典
错误处理 总结 更多Golang资源包:https://github.com/0voice/Introduction-to-Golang 关键字 Go语言设计的关键字,了解这些关键字有助于命名变量的冲突避免 go的二十五个关键字 简介 var 和 const 是 Go语言基础里面的变量和常量申明 package 和 import 用于分包和导入 func 用于定义函数和方法 max(y,z)) // 也可在这直接调用它 } 上面的例子可以看到直接返回了两个参数,当然也可以命名返回参数的变量,这个例子里面只是用了两 个类型,也可以改成如下这样的定义,然后返回的时候不用带上变量名,因为直接在函数里面初始化 了。但如果函数是导出的(首字母大写),官方建议:最好命名返回值,因为不命名返回值,虽然使得代码 更加简洁了,但是会造成生成的文档可读性差。 变参 Go函数支持 以省略前缀的包名,也就是前面调用 的fmt.Println("hello world")可以省略的写成 Println("hello world") 2、别名操作 别名操作顾名思义可以把包命名成另一个用起来容易记忆的名字 别名操作的话调用包函数时前缀变成了前缀,即 f.Println("hello world") 3、_操作 这个操作经常是让很多人费解的一个操作符,请看下面这个0 码力 | 47 页 | 1020.34 KB | 1 年前3Go读书会第二期
社区的优秀项目和代 码,看看他们怎么做的 践行哲学,遵循惯例,认清本质,理解原理 Part2 – 项目基础:布局、代码风格与命名 践行哲学,遵循惯例,认清本质,理解原理 每个 gopher 在开启一个 go 项目时都要考虑的事情 • Go 项目布局 • 代码风格 • 命名惯例 Part3 – 语法基础:声明、类型、语句与控制结构 践行哲学,遵循惯例,认清本质,理解原理 • 一致的变量声明形式0 码力 | 26 页 | 4.55 MB | 1 年前3Hello 算法 1.0.0b1 Golang版
我们将这一摞元素的顶部称为「栈顶」,将底部称为「栈底」,将把元素添加到栈顶的操作称为「入栈」,将删除 栈顶元素的操作称为「出栈」。 Figure 5‑1. 栈的先入后出规则 5.1.1. 栈常用操作 栈的常用操作见下表(方法命名以 Java 为例)。 方法 描述 时间复杂度 push() 元素入栈(添加至栈顶) ?(1) pop() 栈顶元素出栈 ?(1) peek() 访问栈顶元素 ?(1) size() 获取栈的长度 而恰好,堆的定义与优先队列的操作逻辑完全吻合,大顶堆就是一个元素从大到小出队的优先队列。从使用角 度看,我们可以将「优先队列」和「堆」理解为等价的数据结构。因此,本文与代码对两者不做特别区分,统 一使用「堆」来命名。 堆的常用操作见下表(方法命名以 Java 为例)。 8. 堆 hello‑algo.com 124 方法 描述 时间复杂度 add() 元素入堆 ?(log ?) poll() 堆顶元素出堆 ?(log 原地排序:只在递归中使用 ?(log ?) 大小的栈帧空间。 非稳定排序:哨兵划分操作可能改变相等元素的相对位置。 自适应排序:最差情况下,时间复杂度劣化至 ?(?2) 。 11.4.3. 快排为什么快? 从命名能够看出,快速排序在效率方面一定“有两把刷子”。快速排序的平均时间复杂度虽然与「归并排序」 和「堆排序」一致,但实际 效率更高,这是因为: ‧ 出现最差情况的概率很低:虽然快速排序的最差时间复杂度为0 码力 | 190 页 | 14.71 MB | 1 年前3Hello 算法 1.0.0b2 Golang版
hello‑algo.com 68 Figure 5‑4. 队列的先入先出规则 5.2.1. 队列常用操作 队列的常用操作见下表。需要注意,不同编程语言的方法名是不同的,在这里我们采用与栈相同的方法命名。 方法名 描述 时间复杂度 push() 元素入队,即将元素添加至队尾 ?(1) pop() 队首元素出队 ?(1) peek() 访问队首元素 ?(1) 我们可以直接使用编程语言实现好的队列类。 而恰好,堆的定义与优先队列的操作逻辑完全吻合,大顶堆就是一个元素从大到小出队的优先队列。从使用角 度看,我们可以将「优先队列」和「堆」理解为等价的数据结构。因此,本文与代码对两者不做特别区分,统 一使用「堆」来命名。 堆的常用操作见下表,方法名需根据编程语言确定。 8. 堆 hello‑algo.com 127 方法名 描述 时间复杂度 push() 元素入堆 ?(log ?) pop() 堆顶元素出堆 :输入数组完全倒序下,达到最差递归深度 ? 。由于未借助辅助数组空间,因此是“原地排 序”。 非稳定排序:哨兵划分最后一步可能会将基准数交换至相等元素的右边。 11.4.3. 快排为什么快? 从命名能够看出,快速排序在效率方面一定“有两把刷子”。快速排序的平均时间复杂度虽然与「归并排序」 和「堆排序」一致,但实际 效率更高,这是因为: ‧ 出现最差情况的概率很低:虽然快速排序的最差时间复杂度为0 码力 | 202 页 | 15.73 MB | 1 年前3
共 22 条
- 1
- 2
- 3