![](https://img-blog.csdnimg.cn/20210219131816897.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
GO
文章平均质量分 66
go语言相关内容整理
叫我峰兄
星光不问赶路人,干就完了!
展开
-
go语言将要支持泛型啦
早晨浏览公众号,说预计GO将在1.18版本支持泛型,虽然编程多年,但对什么是泛型没什么认识,今天就整理一下什么是泛型,希望对大家也有帮助。在计算机程序设计领域,为了避免因数据类型的不同,而被迫重复编写大量相同业务逻辑的代码,人们发展的泛型及泛型编程技术。那么,什么是泛型呢?本节就带领读者深度剖析一下这个问题。所以泛型,实质上就是不使用具体数据类型(例如 int、double、float 等),而是使用一种通用类型来进行程序设计的方法,该方法可以大规模的减少程序代码的编写量,让程序员可以集中精力用于业务原创 2021-08-26 09:04:17 · 303 阅读 · 0 评论 -
go接口理解
一:接口的定义interface类型可以定义一组方法,但这些方法不需要实现。且interface不能包含任何字段,某个自定义类型(如结构体),需要用到时再具体实现该方法。type 接口名 interface{ method1(参数列表) 返回值列表 method2(参数列表) 返回值列表}func(t 自定义类型)method1(参数列表,返回值列表){ //方法实现}func(t 自定义类型)method2(参数列表,返回值列表){ //方法实现}二:简单使用举例ty原创 2021-07-30 11:15:56 · 106 阅读 · 0 评论 -
new和make的区别
new这是一个用来分配内存的内建函数,但是与C++不一样的是,它并不初始化内存,只是将其置零。也就是说,new(T)会为T类型的新项目,分配被置零的存储,并且返回它的地址,一个类型为*T的值。在Go的术语中,其返回一个指向新分配的类型为T的指针,这个指针指向的内容的值为零(zero value)。注意并不是指针为零。Go语言中的对象没有C++中的构造函数,如果用C来描述,Go中的new大概相当于:T *t = (T*)malloc(sizeof(T))memset(t, 0, sizeof(T))原创 2021-06-08 15:37:52 · 234 阅读 · 0 评论 -
两个nil比较结果是什么
背景哈喽,大家好,我是asong。前几天在一个交流群里看到了一道非常有意思的面试题,今天把它分享出来,我们先来看一下这个道题:fmt.Println(nil== nil)两个nil的比较结果是什么?true、false、还是无法编译?大家先思考着,文中揭晓答案。Go中nil的定义在Go官方文档中,对nil的定义如下:// nil is a predeclared identifier representing the zero value for a// pointer, channel,原创 2021-06-07 08:30:24 · 386 阅读 · 1 评论 -
go 打印 %v %+v %#v 的区别
总结%v 只输出所有的值%+v 先输出字段类型,再输出该字段的值%#v 先输出结构体名字值,再输出结构体(字段类型+字段的值)package mainimport “fmt”type student struct {id int32name string}func main() {a := &student{id: 1, name: “xiaoming”}fmt.Printf("a=%v \n", a)fmt.Printf("a=%+v \n",转载 2021-06-06 16:37:14 · 818 阅读 · 0 评论 -
golang中range在slice和map遍历中的注意事项
package main import ( "fmt") func main() { slice := []int{0, 1, 2, 3} myMap := make(map[int]*int) for _,v :=range slice{ if v==1 { v=100 } } for k,v :=range slice{ fmt.Println("k:",k,"v:",v) }}预想的结果应该是:k: 0 v: 0k: 1 v: 100k: 2原创 2021-06-06 16:35:46 · 736 阅读 · 2 评论 -
go struct{} 空结构体的特点和作用
空结构体的特点和作用参考代码package main import ( "fmt" "unsafe") func main() { empStruct()} //空结构体的实例和作用func empStruct(){ //空结构体的特点:1、不占用内存;2、地址不变 var s struct{} var s1 struct{} fmt.Println("空结构体占用内存的情况:",unsafe.Sizeof(s))原创 2021-06-06 15:59:04 · 141 阅读 · 0 评论 -
Golang结构体中Tag的使用
Golang中可以为结构体的字段添加tag,这类似于Java中为类的属性添加的注解,Golang本身的encoding/json包解析json使用了tag,一些开源的ORM框架,也广泛使用了tag,那么,我们如何通过代码自己实现tag的解析,从而简化结构体字段的使用方式呢?下面看一个例子。假设有一个Person结构体定义如下type Person struct { Name string `label:"Person Name: " uppercase:"true"` Age转载 2021-06-06 15:18:56 · 923 阅读 · 0 评论 -
Swoole协程与Go协程的区别
进程、线程、协程的概念进程是什么?进程就是应用程序的启动实例。例如:打开一个软件,就是开启了一个进程。进程拥有代码和打开的文件资源,数据资源,独立的内存空间。线程是什么?线程属于进程,是程序的执行者。一个进程至少包含一个主线程,也可以有更多的子线程。线程有两种调度策略,一是:分时调度,二是:抢占式调度。协程是什么?协程是轻量级线程, 协程的创建、切换、挂起、销毁全部为内存操作,消耗是非常低的。协程是属于线程,协程是在线程里执行的。协程的调度是用户手动切换的,所以又叫用户空间线程。协转载 2021-05-26 16:19:36 · 204 阅读 · 0 评论 -
你知道几种Go并发控制方式
引言Golang中通过go关键字就可开启一个goroutine,因此,在Go中可以轻松写出并发代码。但是,如何对这些并发执行的groutines有效地控制?提到并发控制,很多人可能最先想到的是锁。Golang中同样提供了锁的相关机制,包括互斥锁sync.Mutex,和读写锁sync.RWMutex。除了锁,还有原子操作sync/atomic等。但是,这些机制关注的重点是goroutines的并发数据安全性。而本文想讨论的是goroutine的并发行为控制。在goroutine并发行为控制中,有三种常见转载 2021-05-26 13:46:52 · 992 阅读 · 0 评论 -
golang gRPC四种模式详解
项目源码地址:https://github.com/wongcony/grpcstudy本项目把四种模式都写成代码供读者查阅。具体的详解可以参考代码注释,在此只讲解gRPC的golang实现中遇到的问题和总结相应的经验。1,简单模式:简单模式只是使用参数和返回值作为服务器与客户端传递数据的方式,最简单。2,客户端流模式:即从客户端往服务器端发送数据使用的是流,即服务器端的参数为流类型,然而在服务器相应后返还数据给客户端,使用的也是流的send方法。一般在服务器端的代码,需要先recv再send,而客户转载 2021-05-14 09:23:46 · 1240 阅读 · 0 评论 -
Go中的struct比较知识点
说明结论指针类型的结构体和数值类型的结构提不能比较同一个结构体的数值类型比较@ 如果结构体中包含:slice(切边,注意: 不是数组), map,function类型不能比较@ 除此之外可以比较同一个结构体的指针类型比较@可以比较,不用管结构体中是否包含不能比较的数据,因为比较的是指针地址不同类型的结构体数值比较@可以先通过强制转换再比较. 强制转换的前提是两个不同结构体除了名字不一样,其他都一样,否则强制转换会报错, 同时也无法比较不同类型的结构体指针比较@不能直接比较@可以先原创 2021-05-14 09:03:05 · 338 阅读 · 3 评论 -
Go语言中defer的一些坑
defer语句是Go中一个非常有用的特性,可以将一个方法延迟到包裹该方法的方法返回时执行,在实际应用中,defer语句可以充当其他语言中try…catch…的角色,也可以用来处理关闭文件句柄等收尾操作。defer触发时机A “defer” statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surroundi原创 2021-05-12 09:19:44 · 428 阅读 · 0 评论 -
go语言局部变量分配在栈还是堆?
一个问题引发的思考?如下go语言代码package main func foo(m0 int) (*int) { var m1 int = 11; return &m1} func main() { m := foo(100) println(*m)编译运行:$ go build main.go && ./main 11竟然没有出现任何编译错误。熟悉C/C++语言的同学,立马就能看出这个程序是存在"问题"的,即函数foo把局部变量m1的地转载 2021-05-08 17:53:05 · 593 阅读 · 0 评论 -
Go语言中对于堆栈理解
在JAVA中相信大家对堆栈应该有个很清晰的认知。什么是堆栈?在计算机中堆栈的概念分为:数据结构的堆栈和内存分配中堆栈。数据结构的堆栈:堆:堆可以被看成是一棵树,如:堆排序。在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的一种数据结构。栈:—种先进后出的数据结构。这里着重讲的是内存分配中的堆和栈。内存分配中的堆和栈栈(操作系统)∶由操作系统自动分配释放,转载 2021-05-08 17:45:33 · 791 阅读 · 0 评论 -
Go 协程:互斥锁和读写锁
在 Golang 里 sync包中专门的方法来实现锁。这个包有两个很重要的锁类型一个叫 Mutex, 利用它可以实现互斥锁。一个叫 RWMutex,利用它可以实现读写锁。1. 互斥锁 :Mutex使用互斥锁(Mutex,全称 mutual exclusion)是为了来保护一个资源不会因为并发操作而引起冲突导致数据不准确。举个例子,就像下面这段代码,我开启了三个协程,每个协程分别往 count 这个变量加1000次 1,理论上看,最终的 count 值应试为 3000package main转载 2021-04-28 09:56:38 · 299 阅读 · 0 评论 -
Go Context
控制并发有两种经典的方式,一种是WaitGroup,另外一种就是Context,今天我就谈谈Context。什么是WaitGroupWaitGroup以前我们在并发的时候介绍过,它是一种控制并发的方式,它的这种方式是控制多个goroutine同时完成。func main() { var wg sync.WaitGroup wg.Add(2) go func() { time.Sleep(2*time.Second) fmt.Println("1号完成") wg.Done() }(转载 2021-04-13 20:26:42 · 104 阅读 · 0 评论 -
Golang的协程调度器原理及GMP设计思想
一、Golang“调度器”的由来?(1) 单进程时代不需要调度器我们知道,一切的软件都是跑在操作系统上,真正用来干活(计算)的是CPU。早期的操作系统每个程序就是一个进程,知道一个程序运行完,才能进行下一个进程,就是“单进程时代”一切的程序只能串行发生。5-单进程操作系统.png早期的单进程操作系统,面临2个问题:1.单一的执行流程,计算机只能一个任务一个任务处理。2.进程阻塞所带来的CPU时间浪费。那么能不能有多个进程来宏观一起来执行多个任务呢?后来操作系统就具有了 最早的并发能力:多转载 2021-04-13 00:01:23 · 654 阅读 · 0 评论 -
go语言常见问题
1. go的锁如何实现,用了什么cpu指令第一种:mutexvar num intvar mtx sync.Mutexvar wg sync.WaitGroupfunc add(){ mtx.Lock() defer mtx.Unlock() defer wg.Done() num+=1}func main(){ for i:= 0; i < 100; i++{ wg.Add(1) go add() } wg.Wait()}第二种 使用chan实现原创 2021-04-12 22:26:02 · 398 阅读 · 0 评论 -
Go语言初始化结构体的几种方式
结构体在实例化时可以直接对成员变量进行初始化,初始化有两种形式分别是以字段“键值对”形式和多个值的列表形式,键值对形式的初始化适合选择性填充字段较多的结构体,多个值的列表形式适合填充字段较少的结构体。使用“键值对”初始化结构体结构体可以使用“键值对”(Key value pair)初始化字段,每个“键”(Key)对应结构体中的一个字段,键的“值”(Value)对应字段需要初始化的值。键值对的填充是可选的,不需要初始化的字段可以不填入初始化列表中。结构体实例化后字段的默认值是字段类型的默认值,例如 ,原创 2021-02-19 13:03:02 · 1251 阅读 · 0 评论 -
GO基本规则
一.工作区和GOPATH工作区是放置Go源码文件的目录一般情况下,Go源码文件都需要存放在工作区中,但对于命令源码文件,这不是必须的src目录用于存放源码文件以代码包为组织形式pkg目录用于存放归档文件(名称以.a为后缀的文件)bin目录用于存放当前工作区中的Go程序的可执行文件当环境变量GOBIN已有效设置时,该目录会变的无意义当GOPATH的值中包含多个工作区的路径时,必须设置GOBIN,否则无法成功安装GO程序的可执行文件二.源码文件的分类和含义分三类1.命令源码文件:原创 2021-02-13 08:47:02 · 287 阅读 · 0 评论 -
GO命令基础
go run命令简介用于运行命令源码文件只能接受 一个命令源码文件以及若干个库源码文件作为文件参数其内部操作步骤:先编译源码文件再运行go run 常用标记的使用-a :强制编译相关代码,不论他们的编译结果是否已是最新的-n: 打印编译过程中所需运行的命令,但不真正执行他们-p n:并行编译,其中n为并行的数量-v: 列出被编译的代码包的名称-work:显示编译时创建的临时工作目录的路径,并且不删除它-x:打印编译过程中所需运行的命令,并执行他们go build命令简介用于编译源码原创 2021-02-13 09:12:33 · 72 阅读 · 0 评论 -
GO语言基本数据类型
Go语言-程序实体与关键字任何Go语言源码文件都由若干个程序实体组成的。在Go语言中,变量、常量、函数、结构体和接口被统称为“程序实体”,而它们的名字被统称为“标识符”。标识符可以是任何Unicode编码可以表示的字母字符、数字以及下划线“_”。不过,首字母不能是数字或下划线。注意:在Go语言中,我们对程序实体的访问权限控制只能通过它们的名字来实现。名字首字母为大写的程序实体可以被任何代码包中的代码访问到。而名字首字母为小写的程序实体则只能被同一个代码包中的代码所访问。关键字:不能把关键字作为原创 2021-02-13 09:25:02 · 163 阅读 · 0 评论