Go
文章平均质量分 78
go语言相关分享
cheniie
从今去把她忘却,只此长醉了余生。
展开
-
Go导入私有仓库
这个问题其实分两种情况来看,如果你自己的仓库是一个“正规”的仓库,使用域名访问,不带端口,通过HTTPS访问,唯一的区别是你的仓库是私有的。最后的最后,如果你使用的是GoLand或者IDEA,这类IDE好像有自己的环境变量机制,直接修改系统环境变量有时候不会生效,你需要在IDE里面设置或者在它的命令行通过。接下来就是比较复杂的情况,比如仓库是非标的,通过IP地址访问,或者需要带端口访问,还有只能通过HTTP访问等。如果你只有某个组下的仓库是私有的,可以通过路径指定,多个域名通过逗号分隔。原创 2024-04-09 13:59:02 · 913 阅读 · 0 评论 -
【Go】泛型
Go1.17引入了泛型的特性,1.18正式开放泛型,本文介绍了Go语言泛型的基本语法,使用示例,以及简要的实现原理,帮助你了解Go的泛型。原创 2022-12-09 18:09:16 · 2261 阅读 · 0 评论 -
Go工作空间
工作空间是Go 1.18新添加的特性,英文名叫`workspace`,同时还有和工作空间相关的命令`go work`。工作空间与Go模块是完全不同的概念。模块是代码组织的一种方式,工作空间本质上是一个目录,它影响的是编译器的工作,只在开发人员的本地发挥作用。工作空间的出现是为了方便多模块开发模式,本文将会介绍任何使用工作空间进行开发。原创 2022-10-30 23:03:11 · 3186 阅读 · 0 评论 -
【Go】内置容器container
Go标准库的包提供了3个包,分别是heap,list,ring,分别实现了堆,链表和环形链表。原创 2022-07-06 21:15:02 · 355 阅读 · 0 评论 -
【Go】如何正确理解error
Go error从诞生之初就招人诟病,人们总是调侃写Go代码有一半都是。但其实大家都没有正确的去理解和看待error这个东西,这也是我写本篇文章的目的。原创 2022-07-02 17:45:40 · 1265 阅读 · 2 评论 -
【Go】FLV文件解析(四)
Go语言FLV文件解析最终章,详解FLV video tag基本格式与解码过程。原创 2022-06-03 19:59:05 · 599 阅读 · 0 评论 -
【Go】FLV文件解析(三)
Go语言解析FLV文件第三期,重点讲述了音频编码相关内容以及音频标签的解码过程。原创 2022-06-03 15:56:36 · 558 阅读 · 0 评论 -
【Go】FLV文件解析(二)
书接上回,我们继续来解析FLV文件的内容,这次要解析的是元数据Tag的内容,需要注意的是不是每个FLV文件都有这个Tag的。在有些教程中,元数据Tag也被称作Script Tag。在官方文档中其实是称作Data Tag,其中的内容称为ScriptDataObject。不管叫什么,你需要知道的是我们在讨论同一个东西。ScriptDataObject的编码格式是AMF,全称Action Message Format。也是Adobe出品,一共有两个版本,为了区分,将先前的版本称为AMF0,新的版本称为AMF3。.原创 2022-06-01 13:54:23 · 1007 阅读 · 0 评论 -
【Go】FLV文件解析(一)
这是一个系列教程,一是为了解释FLV文件的结构,二是为了练习Go语言,希望大家多多支持。在实战编码之前,我们需要首先了解FLV文件的格式。FLV是adobe出品的视频封装格式,注意它只是封装格式,不是编码格式。做为第一节的内容,我们不会过度深入音视频数据的编码,这部分内容以后会再讲。FLV文件格式FLV文件由FLV Header和FLV Body组成,FLV Body又由许多Tag组成,Tag里面可能是视频、音频或脚本。这里所说的脚本并不是可执行脚本,而是视频的一些元信息。在每一个Tag的前面还有一个原创 2022-05-31 10:40:09 · 1102 阅读 · 1 评论 -
Go切片转字符串发生了啥
在Go语言中,字节切片和字符串的转换非常丝滑。但是你有没有想过,在强制类型转换的过程中都发生了什么,有没有内存拷贝?本文将为你解开这两个问题的答案。有没有发生内存拷贝是很容易证明的一件事,我们可以通过下面的代码来证明这一点。func main() { bs := []byte{'h', 'i'} p1 := unsafe.Pointer(&bs) ss := string(bs) p2 := unsafe.Pointer(&ss) fmt.P原创 2022-05-24 21:05:59 · 1691 阅读 · 0 评论 -
Go调试器Delve
Delve是Go官方推荐的调试器,我们熟知的Goland、LiteIDE都集成了Delve,同时各大通用IDE如VSCode、Atom、Sublime等的Go插件也都集成了Delve调试Go代码。除了IDE以外,还有一个使用Delve的GUI调试器——Gdlv。除了提供图形界面外,Gdlv也可以执行Delve命令。开始第一步需要安装Delve。Go1.16及以上版本:$ go install github.com/go-delve/delve/cmd/dlv@latest$ go install原创 2022-04-15 21:36:51 · 1822 阅读 · 0 评论 -
Go编译指令
许久之前,我曾写过一篇go条件编译的文章,如今又出现了第三种方式,顺便介绍下Go的编译指令。Go编译指令必须放在文件开头,和代码或普通注释之间要有空行。基本格式是://go:指令 [值]... ...go:build//go:build功能和// +build一样。只不过在go 1.17这个版本才实现对//go:build的支持。在go\src\go\build\constraint\expr.go中有一段注释:// This package parses both the origina原创 2022-04-09 12:30:13 · 13206 阅读 · 0 评论 -
go get问题记录②
三年前我曾写过一篇关于go get问题记录的文章,没想到三年后会再次遇到它出问题。不过这次的问题是代理的问题,虽然顺利解决了问题,但是细思之下还是有些问题值得探究一番。问题解决我的问题出自GOPROXY环境变量配置的代理不可用了,导致go get下载包一直报错。解决方案是配置一个可用的代理。在这里介绍3个国内代理:七牛云阿里云GOPROXY.IO,我之前就是用这个,发现不可用了。关于GOPROXY的配置方法在上面三个网站都有详细介绍。顺便提一下,阿里云镜像网站还有很多别的资源,原创 2022-03-26 14:20:05 · 938 阅读 · 0 评论 -
Go字符串模板替换
如果要在Go语言中做字符串模板替换,比如配置模板实例化,你会如何做呢?fmt.Sprintf大概率是多数人首先想到的方式,但今天我们的主角是os.Expand。先来个栗子开胃。var config = `app.name = ${appName}app.ip = ${appIP}app.port = ${appPort}`var dev = map[string]string{ "appName": "my_app", "appIP": "0.0.0.0", "appPort":原创 2021-10-22 00:29:41 · 6287 阅读 · 0 评论 -
Go汇编之函数
目录认识寄存器伪寄存器访问语法汇编指令语法函数调用参数和返回值局部变量函数帧输出汇编代码首先需要明确的一点是你写的汇编代码和最终编译的汇编代码是不一样的。所以当你学完了Go汇编入门,然后想从go tool compile -S -N -l xxx.go开始实践时,往往会发现它和你想象的不一样。比如函数帧会多出8个字节,局部变量偏移也不对,这是因为编译器输出的汇编代码会自动保存BP寄存器,并且加入了维护真SP寄存器的代码,而这些编译器会自动帮你完成,所以编写汇编代码是不用处理这些的。另外你会发现编译器输出的原创 2021-06-10 23:36:42 · 639 阅读 · 0 评论 -
Go汇编之全局变量
在.go文件中声明全局变量,在.s文件中初始化。先看操作。第一步:新建main.go和var.s文件第二步:在main.go中输入如下代码package mainimport ( "fmt")var Id intfunc main() { fmt.Println(Id)}第三步:在var.s中输入如下代码#include "textflag.h"GLOBL ·Id(SB),NOPTR,$8DATA ·Id+0(SB)/1,$0x37DATA ·Id+1(SB)/1,原创 2021-05-11 11:13:48 · 1185 阅读 · 4 评论 -
Go语言的errors
Go语言的errors包有4个方法:errors.Aserrors.Iserrors.Newerrors.Unwrap本期我们来揭开他们的神秘面纱。俗话说的好,柿子还得挑软的捏,按照国际惯例我们先从最简单的New函数开始。在 Go 源码目录的 errors 目录下,有errors.go和wrap.go两个文件,以及对应的errors_test.go和wrap_test.go两个单元测试文件。要学一个新东西时,其实看xxx_test.go是一个非常不错的选择,它会告诉你这些函数该怎么用。说回原创 2021-05-08 20:51:44 · 1745 阅读 · 0 评论 -
优雅的处理Go错误
错误处理属于编程中非主要但不可或缺的部分,优雅的错误处理不仅能让业务逻辑更清晰,还提高身心健康。错误处理Go支持多返回值,因此Go对错误的处理模式是将错误作为返回值返回。刚接触Go时,你一定会对return nil, err这样的代码记忆尤新,同时也会对大量的if err != nil感到力不从心。将错误在返回值中返回的好处是你必须显示处理所有的错误,或者使用_显示忽略。缺点是需要写大量的if err != nil,这一步无法省略,但是可以减少类似的代码,当然,前提是业务逻辑是类似的。我们以一个序列原创 2021-05-07 13:11:51 · 389 阅读 · 0 评论 -
Go如何更优雅的构造结构数据
场景:你需要根据一些参数来构造一个结构体,但是有不想让用户直接构造这个结构体,于是不得不提供一个函数来构造结构体。由于Go不支持重载,你不得不编写各种参数的构造函数,对于命名困难户来说,无异于噩梦。我们通过一个例子来看如何优雅的解决这个问题。假设我们有一个drawer包:package drawertype Drawer interface { DrawLine(p1, p2 Point) DrawText(p Point, text string) DrawCircle(p Point, r原创 2021-04-01 22:38:48 · 446 阅读 · 0 评论 -
Go环境搭建那些事
请前往下载。傻瓜式安装,选着一下安装目录,无脑下一步。安装完成后打开cmd输入go version测试安装是否成功。如果找不到命令,将Go安装目录下的bin目录添加到 Path 环境变量。新版本的Go会自动添加,无需手动添加。原创 2021-03-27 17:01:53 · 131 阅读 · 0 评论 -
go一个不错的uuid库
github.com/google/uuid可以生成纯数字的uuid文档原创 2021-03-24 14:08:26 · 3081 阅读 · 0 评论 -
go条件编译
文章目录go条件编译示例第一个问题后缀规则编译标签第二个问题条件编译的实现go条件编译条件编译按字面解释就是满足某个条件的情况下编译某个文件。这里有两个问题:如何设定条件?如何给定条件?再回答这两个问题之前,我们先来看一个传统的hello world例子。示例新建Go项目:|–helloworld|------main1.go|------main2.gomain1.go内容如下:// +build hellopackage mainfunc main() { pr原创 2021-03-16 21:10:26 · 1710 阅读 · 0 评论 -
path.Dir? filepath.Dir? 傻傻分不清楚
Go语言关于路径的操作有path和filepath两个包。他们都可以处理路径相关炒作,但你是否疑惑过这两个包该用哪个?它们有什么区别呢?小小的脑袋充满大大的疑惑呢。它们的区别其实看看源码就明白了,path.Dir源码在path/path.go,filepath.Dir源码在path/filepath/path.go。在path/path.go文件开头有这样一段注释:// Package path implements utility routines for manipulating slash-s原创 2021-03-09 18:24:35 · 2578 阅读 · 1 评论 -
大端,小端,go
什么是大端序和小端序?如何快速区分大端序和小端序?为什么会有大端序和小端序?go如何处理二进制序列化?让我们来聊聊大端序小端序,以及go语言是如何处理的。主要是回答上面4个问题。大端序和小端序的概念大家都知道:大端序是数据的低字节放在高地址,高字节放在低地址。小端序是数据的低字节放在低地址,高字节放在高地址。它其实代表了一种数据处理的顺序,在数据传输和存储中,我们先处理高字节,那就是大端序,先处理低字节,就是小端序。为什么在我们熟知的定义中,会出现字节和地址的对应呢?它其实是对数据.原创 2021-03-05 22:03:05 · 2224 阅读 · 1 评论 -
go反射与接口
在go反射的秘密一文中,我从源代码的角度分析了go反射的相关细节,但是在那篇文章中,还是留下了两个疑问:为什么TypeOf函数的实现是直接强制类型转换?一个具体类型的变量是如何转成interface的?由于当时的我年少无知,没能解答出这两个问题。时过境迁,再次读书的时候偶然明悟,遂作此文以解惑。让我们再次回顾一下TypeOf函数的源码:/*--type.go--*/func TypeOf(i interface{}) Type { eface := *(*emptyInterface)(u原创 2021-02-26 15:24:39 · 295 阅读 · 0 评论 -
Go文件操作
golang的os包提供了文件想关的操作,打开,关闭,创建,删除等。filepath包则提供了路径相关的操作,如绝对路径,相对路径,取文件名,取后缀名,取路径等。判断文件是否存在://path既可以是目录路径,也可以是文件路径if err := os.Stat(path); err == nil { //文件存在} else { //文件不存在}创建文件:out, err := os.Create("F://a.bmp")if err != nil { //创建文件失败原创 2021-02-15 01:30:38 · 335 阅读 · 0 评论 -
②Go命令:build
go build [-o output] [-i] [build flag] [packages]应该没有人不熟悉这个命令吧,这是go的编译命令,可以用来编译可执行程序或包。它会忽略_test.go结尾的文件,go编译器将它们识别为测试代码。默认情况下,可执行程序编译成.exe文件,文件名是main.go所在的目录名。包编译结果会被丢弃,仅仅是检查它能编译通过。-o参数用来指定编译结果输出位置,可以是文件,也可以是目录。目录是否存在是会影响命令执行结果的:如果目录存在,则将编译结果放到指定目录下原创 2021-02-15 00:33:58 · 1655 阅读 · 0 评论 -
①Go命令:bug
go bug这应该是唯一一个与编程无关的命令了,它的作用是在浏览器打开一个Issue,并帮你初始化一个模板,没有任何副作用。不得不说想得很周到,但是凭我的水平应该是用不到这个命令了。模板中包含两项重要信息:go版本和go环境变量。其实也是通过go version和go env命令获取的。...原创 2021-02-14 21:54:51 · 252 阅读 · 0 评论 -
三色标记法
go语言的gc采用了三色标记法。三色标记法将对象标记为黑、白、灰三种颜色,黑色对象为可达对象,应该保留,白色对象为不可达对象,应该被清除,灰色作为中间过度态。下面以链表为例,介绍三色标记-清除法的过程。假设我们新建了三个结点A、B、C,其中,A和B是头结点,C是B的下一个节点,一般头结点都是可达的。由于GC周期还没开始,所以这三个对象都属于白色集合。接着我们新建节点D,并作为A的下一个节点。注意,此时D将被放置在灰色集合中!因为有这样一条规则:当一个指针域变化时,则该指针指向的对象需要变色原创 2021-02-14 19:50:30 · 2861 阅读 · 0 评论 -
go反射的秘密
前篇说了Go语言中反射的一些注意事项,现在让我们来看看反射背后的小秘密。前方检票上车,做好读源代码的准备。在每段源代码的开头,我都会标出所在文件。首先从TypeOf函数开始,该函数在\src\reflect\type.go文件中定义。/*--type.go--*/func TypeOf(i interface{}) Type { eface := *(*emptyInterface)(unsafe.Pointer(&i)) return toType(eface.typ)}该函数首先原创 2021-02-14 19:31:20 · 474 阅读 · 1 评论 -
Go反射
反射用来获取对象的信息,包括类型和值等等。有时候我们希望屏蔽类型之间的差别,比如我们希望一个可以接收任何类型的函数。有时候我们又希望搞清楚这种差别,例如我们希望在函数中对不同类型的变量做不同的计算。对于前者,我们有interface{}类型可以屏蔽掉变量之间的类型差别。对于第二点,我们有反射。要获得一个变量的信息,那么这些信息必须事先存储在某个地方,具体来说是运行时系统持有变量的信息,反射就是将这些变量信息暴露出来。在golang中,变量包含两个部分:类型和值。因此反射应该至少能获得这两个信息。在原创 2021-02-14 19:27:13 · 179 阅读 · 0 评论 -
Go与Redis
文章目录Redis安装与启动WindowsLinux配置RedisRedis命令Redis键Redis数据类型发布订阅事务安全持久化主从复制一主多从薪火相传哨兵模式Golang使用Redismonnand/goredisgosexy/redisRedis安装与启动Windows我用的是Windows,所以先说说Windows下的安装过程。在多数情况下,你下载到的可能是一个压缩包,安装过程就是找个地方解压出来就OK了。解压之后能看到redis-cli.exe和redis-server.exe这两个文件原创 2021-02-14 19:13:47 · 776 阅读 · 0 评论 -
取消STW的栈重新扫描
STW:Stop The Word☞原文传送摘要在Go 1.7中,主要的STW时间消耗来自栈重新扫描。我们建议通过切换到混合写屏障来消除对堆栈重新扫描的需要,该屏障结合了Yuasa风格的删除写屏障和Dijkstra风格的插入写屏障。初步实验表明,这可以将最坏情况的STW时间减少到50μs以下,并且这种方法可能同时消除标记终止时的STW。消除堆栈重新扫描将反过来简化和消除垃圾收集器的许多其他部分,这些部分仅用于提高堆栈重新扫描的性能。比如栈屏障(在运行时的许多部分引入了显著的复杂度)以及维护重新扫.翻译 2021-02-14 18:32:10 · 448 阅读 · 1 评论 -
go http服务的背后
文章目录服务器处理器处理器函数多路复用器背后的秘密(1)殊途同归(2)绕不开的服务器(3)无限循环(4)连接(5)回到原点复用器的真相(1)Handler(2)handler(3)match注册路由结论首先我们需要总结一下开启一个HTTP服务的几种方式:通过http开启HTTP服务。package mainimport ( "fmt" "net/http")func hello(w http.ReponseWriter, request *http.Request) { .原创 2021-02-14 18:18:38 · 205 阅读 · 0 评论 -
地鼠搬砖
我们都知道Go语言是原生支持语言级并发的,这个并发的最小逻辑单元就是goroutine。goroutine就是Go语言提供的一种用户态线程,当然这种用户态线程是跑在内核级线程之上的。当我们创建了很多的goroutine,并且它们都是跑在同一个内核线程之上的时候,就需要一个调度器来维护这些goroutine,确保所有的goroutine都使用cpu,并且是尽可能公平的使用cpu资源。这个调度器的原理以及实现值得我们去深入研究一下。支撑整个调度器的主要有4个重要结构,分别是M、G、P、Sched,前三个定义.原创 2021-02-14 18:11:07 · 289 阅读 · 0 评论 -
go结构体内存对齐
当你在编辑器里谢谢type xxx struct时,是否想过这个结构体在内存中究竟占用多少字节呢?那还不简单,把所有字段的字节数加起来不就好了。朋友,如果你这样想,那就太草率了。基本概念由于内存对齐的原因,结构体实际占用字节数永远大于等于结构体所有字段字节数之和。没错,确实有正好相等的情况,后面我们会看到在一种什么样的机缘巧合之下他们会恰好相等。对于结构体的每个字段,我们先来认识一下如下4个概念:对齐宽度本身所占字节数实际占用字节数偏移量那么他们之间有什么关系呢?对齐宽度≤本身所占原创 2020-11-23 21:01:19 · 1552 阅读 · 1 评论 -
go格式化输出动词
Go语言格式化输出动词:动词功能%v按值本身的格式输出,万能动词,不知道用什么动词就用它%+v同%v,但输出结构体时会添加字段名%#v输出值得Go语法表示%t格式化bool值%b按二进制输出%c输出整数对应的Unicode字符%d按十进制输出%o按八进制输出%O按八进制输出,并添加0o前缀%x按十六进制输出,字母小写,%x还能用来格式化字符串和[]byte类型,每个字节用两位十六进制表示,字母小写%X按十原创 2020-10-30 20:17:29 · 429 阅读 · 0 评论 -
golang短变量命名空间问题
场景一package mainfunc main() { a := 1 println(&a) a, b := 2, true println(b) println(&a)}/** 结果0xc000085f48true0xc000085f48*/分析:由于在相同的命名空间下,a, b := 1, true中的变量a并没有覆盖掉之前定义的a变量,仅仅是创建了变量b。如果将b换成_,上面的代码会报:=没有新变量产生的错误,也可佐证。场景二package mai原创 2020-10-21 14:46:03 · 890 阅读 · 1 评论 -
golang反向代理无法访问
golang原生提供的httputil库可以非常方便的实现反向代理。那么到底有多简单呢?如果只实现一个简单的定向代理,main函数里只需要写3行代码!package mainimport ( "net/http" "net/http/httputil" "net/url")func main() { u, _ := url.Parse("http://localhost:888...原创 2019-12-10 23:21:01 · 2127 阅读 · 0 评论 -
地鼠宝宝的轶事奇闻之线程模型
Golang并发机制Golang并发机制线程模型三大核心M、P、G、KSE(内核调度实体)之间的关系MM的创建M的初始化M的停止M的限制P设置P的最大数量GM、P、G的容器线程模型在操作系统提供的内核线程之上,go搭建了一个两级线程模型。毫无疑问,其中一级必然是内核线程,另一级便是goroutine。你可以将goroutine看作是应用程序线程。goroutine一词是由go的开发者们专门创建的,...原创 2018-06-05 21:06:39 · 242 阅读 · 0 评论