GOLang
帅_shuai_
用自己的努力去收获自己的未来
展开
-
GoLang 读取CSV文件
使用GoLang读取CSV文件。原创 2022-09-13 16:26:12 · 2848 阅读 · 0 评论 -
GoLang 测试
测试组和子测试我们都知道可以通过-run=RegExp来指定运行的测试用例,还可以通过/来指定要运行的子测试用例,例如:go test -v -run=Split/simple只会运行simple对应的子测试用例基准测试1.基准测试事例基准测试以Benchmark为前缀,需要一个*testing.B类型的参数b,基准测试必须要执行b.N次,这样的测试才有对照性,b.N的值是系统根据实际情况去调整的,从而保证测试的稳定性2.性能比较函数上面的基准测试只能得到给定操作的绝对耗时,但是在很多性能问题是原创 2022-06-01 20:23:25 · 347 阅读 · 1 评论 -
GoLang HTTP_Server
goLang Http原创 2022-06-01 13:35:27 · 238 阅读 · 0 评论 -
GoLang补充提升(七)
GoLang补充提升(七)1.互斥锁互斥锁是一种常用的控制共享资源访问的方法,它能够保证同一时间只有一个 goroutine 可以访问共享资源。Go 语言中使用sync包中提供的Mutex类型来实现互斥锁。var num int = 0var wg sync.WaitGroupvar lock sync.Mutexfunc add() { for i := 0; i < 50000; i++ { lock.Lock() num++ lock.Unlock() } wg.原创 2022-05-30 15:07:04 · 144 阅读 · 0 评论 -
GoLang 异步日志库实现
GoLang 异步日志库实现公共的方法type LogLevel uint8const ( L_DEBUG LogLevel = iota L_WARNING L_ERROR)func getLogLevel(level LogLevel) string { switch level { case L_DEBUG: return "DEBUG" case L_WARNING: return "WARNING" case L_ERROR: return "ERROR原创 2022-05-29 20:12:23 · 584 阅读 · 0 评论 -
GoLang补充提升(六)
GoLang补充提升(六)1.strconv标准库func main() { //str := "1000" //int(str)这种转换是错误的方式 //i := string(1000)这种转换是错误的方式 //1.可以使用strconv包中的ParseInt方法 i1, err := strconv.ParseInt("1000", 10, 64) //10进制,64位 if err != nil { fmt.Println(err) return } fmt.Print原创 2022-05-29 16:31:55 · 233 阅读 · 0 评论 -
GoLang补充提升(五)
GoLang补充提升(五)1.反射TypeOf(1)基本反射func main() { var a int64 = 100 var b float64 = 3.1415926 reflectType(a) reflectType(b)}func reflectType(a any) { t := reflect.TypeOf(a) fmt.Printf("type:%v\n", t)}(2)type name和type kind在反射中关于类型还划分为两种:类型(Type)原创 2022-05-29 10:04:54 · 168 阅读 · 0 评论 -
GoLang补充提升(四)
GoLang补充提升(四)1.向文件中间插入内容没有直接的办法往文件中间插入内容可以先读出文件写入临时文件,然后再写入要插入的文件,最后将剩余文件写入临时文件中,将之前的文件用临时文件覆盖例如我想向ab之间插入一段话abzzsfunc main() { func1()}func func1() { file, err := os.OpenFile("zzs.txt", os.O_RDWR, 0) if err != nil { fmt.Println(err) re原创 2022-05-28 09:59:19 · 319 阅读 · 0 评论 -
GoLang补充提升(四)
GoLang补充提升(四)1.指针接收者实现接口和值接收者实现接口type person struct { name string}func (p person) speak(info string) { fmt.Println(p.name, ":", info)}type speaker interface { speak(info string)}值接收者实现接口p := person{name: "zzs"}p := &person{name: "zzs"}原创 2022-05-26 16:11:15 · 176 阅读 · 0 评论 -
GoLang补充提升(三)
GoLang补充提升(三)1.panic和recover注意:defer recover要定义在可能出错的地方之前func main() { f1() f2() f3()}func f1() { fmt.Println("F1")}func f2() { defer func() { err := recover() fmt.Println(err) fmt.Println("错误恢复") }() panic("发生严重错误!") fmt.Println("原创 2022-05-26 09:35:04 · 94 阅读 · 0 评论 -
GoLang补充提升(二)
GoLang补充提升(二)1.Slice切片的截取问题数组是值传递切片是引用传递切片本质上是数组中截取的一段创建切片时会底层自动创建数组当在不扩容的情况下,可以改变底层数组来使切片的值改变,反之亦然func main() { arr := [...]int{1, 2, 3, 4, 5, 6, 7} fmt.Println(arr) s1 := arr[0:4] s2 := arr[1:4] fmt.Println(s1) fmt.Println("len:", len(s1),原创 2022-05-25 13:47:37 · 81 阅读 · 0 评论 -
GoLang补充提升(一)
GoLang补充提升(一)1.关于变量的补充全局变量可以只声明不使用,但是局部变量不行//全局变量可以只声明不使用,但是局部变量不行var ( name string age int sex bool)2.const iota 枚举值的使用const ( _ = iota KB = 1 << (iota * 10) MB = 1 << (iota * 10) GB = 1 << (iota * 10) TB = 1 <<原创 2022-05-24 15:45:04 · 156 阅读 · 0 评论 -
GoLang 即时通讯系统(二)
GoLang 即时通讯系统(二)用户消息广播功能用户发送消息给服务器后,服务器需要将这条消息广播个当前的所以在线用户用户业务封装处理讲业务逻辑抽离到User类中,属于User类的上线,下线,发消息都封装到User类中在线用户查询名称修改超时强踢通过管道去触发定时器私聊功能解析客户端发送的字符串,根据规则进行拆分从服务器中寻找相应的名称,进行单一发送即可具体脚本*mainfunc main() { s := NewServer("127.0.0.1原创 2022-05-13 17:13:10 · 536 阅读 · 0 评论 -
GoLang 即时通讯系统(一)
GoLang 即时通讯系统(一)基础Server的构建目录结构servertype Server struct { Ip string Port int}func NewServer(ip string, port int) *Server { return &Server{ Ip: ip, Port: port, }}func (s *Server) handler(conn *net.TCPConn) { fmt.Println("[Serve原创 2022-05-13 11:25:34 · 949 阅读 · 0 评论 -
GoLang 知识点补充(二)
GoLang 知识点补充(二)GoLang 反射解析结构体标签type Person struct { Name string `info:"这是名称" doc:"我的名字"` Sex bool `info:"这是性别"`}func findTag(obj interface{}) { t := reflect.TypeOf(obj).Elem() for i := 0; i < t.NumField(); i++ { tagInfo := t.Field(i).Tag.G原创 2022-05-13 09:52:08 · 179 阅读 · 0 评论 -
GoLang 知识点补充(一)
GoLang 知识点补充(一)1.变量的多行定义 var ( aa int = 10 bb string = "zzs" cc bool = false dd float32 = 3.14 ) fmt.Printf("aa:%d,bb:%s,cc:%t,dd:%f", aa, bb, cc, dd)2.iota知识点测试代码const ( BEIJING = iota SHANGHAI TIANJIN)const ( a = 10 * iot原创 2022-05-12 17:08:26 · 305 阅读 · 0 评论 -
基于GoLang的MMO游戏服务器(四)
基于GoLang的MMO游戏服务器(四)世界聊天首先定义世界聊天的路由方法具体实现type WorldChatAPI struct { znet.BaseRouter}func (wca WorldChatAPI) Handle(request ziface.IRequest) { pid, err := request.GetConnection().GetProperty("pid") if err != nil { fmt.Println(err) return }原创 2022-05-11 17:39:05 · 543 阅读 · 0 评论 -
基于GoLang的MMO游戏服务器(三)
基于GoLang的MMO游戏服务器(三)项目结构Player服务器中每连接一个客户端,相当于一个玩家,封装一个Player结构体type Player struct { Pid int32 Conn ziface.IConnection X float32 Y float32 Z float32 V float32}初始化一个玩家玩家发送消息给客户端func (p *Player) SendMsg(msgID uint32, dat原创 2022-05-11 17:07:58 · 792 阅读 · 0 评论 -
GoLang 操作MongoDB数据库
GoLang 操作MongoDB数据库数据库中的数据结构定义的结构体bson:"xxx"用来映射在MongoDB中的名称,如果不写默认小写type Student struct { Name string `bson:"Name"` Age int `bson:"Age"` Sex bool `bson:"Sex"` IsDelete bool `bson:"IsDelete"`}下载对应操作数据库的包go.mongodb.org原创 2022-05-10 21:42:46 · 1144 阅读 · 0 评论 -
基于GoLang的MMO游戏服务器(二)
基于GoLang的MMO游戏服务器(二)Protobuf的使用配置环境proto的环境配置百度一下就好了(这里不介绍了)先下载Proto的代码包Protobuf的GitHub的传送门注意,现在使用的版本高于V1.4,根据官网的介绍,需要使用google.golang.org/protobuf替换,不然会报错的进入protobuf目录进入protoc-gen-go目录下进行go build进行go install如果出现:go: github.com/google/go-cmp@v0.原创 2022-05-09 20:32:25 · 875 阅读 · 0 评论 -
基于GoLang的MMO游戏服务器(一)
基于GoLang的MMO游戏服务器(一)AOI兴趣点在游戏开发中,客户端的角色往往有很多,有些角色并不用显示出来,只要显示当前角色周围的其它角色就行,角色的信息都是存储在服务器中的,所以服务器需要计算客户端角色周围的其它角色,然后通知给客户端AOI格子类型格子需要自己的ID最大最下XY坐标当前格子中的所有角色的ID以及用来读写的锁对外提供Add添加玩家ID的方法,Remove移除玩家ID的方法,以及获取当前格子中全部ID的方法type Grid struct { GID原创 2022-05-09 20:05:18 · 1888 阅读 · 0 评论 -
使用GoLang开发游戏服务器(十)
使用GoLang开发游戏服务器(十)连接属性开发有时候需要允许用户在外部设置connection的属性在IConnection中定义方法在Connection结构体中定义属性,并实现方法func (c *Connection) SetProperty(key string, value interface{}) { c.PropertyLock.Lock() defer c.PropertyLock.Unlock() c.Properties[key] = value}func原创 2022-05-08 10:28:05 · 1046 阅读 · 1 评论 -
使用GoLang开发游戏服务器(九)
使用GoLang开发游戏服务器(九)连接管理模块服务器需要存储每个连接进入服务器的connection对象,以便于进行管理新增接口IConnectionManagertype IConnectionManager interface { AddConnection(conn IConnection) RemoveConnection(conn IConnection) GetConnection(connID uint32) (IConnection, error) GetConnect原创 2022-05-08 09:43:45 · 759 阅读 · 0 评论 -
使用GoLang开发游戏服务器(八)
使用GoLang开发游戏服务器(八)开辟任务池限定业务之前的框架结构虽然以及能完成逻辑了,但是如果有大量的客户端接入,有一个客户端接入就要对应一个reader的Goroutine和一个writer的Goroutine以及一个处理消息的Goroutine,那么要是有10w个客户端接入,就要有30w个Goroutine,10w个reader和writer是不可避免的,它们处于阻塞状态不会消耗CPU资源,需要优化10w个处理消息的Goroutine我们可以只开辟一定数量的Goroutine来进行处理,大原创 2022-05-07 16:12:01 · 753 阅读 · 0 评论 -
使用GoLang开发游戏服务器(七)
使用GoLang开发游戏服务器(七)读写分离模型之前的框架要发送消息,直接就发送出去了现在需要将写消息单独拿出来,和读消息分离开使用channel管道传递数据新增写数据的方法func (c *Connection) StartWriter() { fmt.Println("Writer Goroutine Start...") defer fmt.Println("Writer is Exit Remote Addr is:", c.RemoteAddr().String()) fo原创 2022-05-07 09:34:51 · 1078 阅读 · 0 评论 -
使用GoLang开发游戏服务器(六)
使用GoLang开发游戏服务器(六)消息管理模块开发之前的框架只能处理一种类型的消息,只有一个路由,但是业务中往往有很多不同类型的消息要处理,所以需要框架能处理各种消息,并且让用户在外部定义新增IMessageHandler.go接口文件type IMessageHandler interface { DoMessageHandler(request IRequest) AddRouter(msgID uint32, router IRouter)}新增MessageHandler.原创 2022-05-06 21:05:33 · 1024 阅读 · 0 评论 -
使用GoLang开发游戏服务器(五)
使用GoLang开发游戏服务器(五)Message消息模块的定义Message消息模块主要用于放在Request中的变量,便于知道包的ID和长度,以便处理黏包新增imessage.go接口脚本type IMessage interface { GetMsgID() uint32 GetMsgLength() uint32 GetMsgData() []byte SetMsgID(id uint32) SetMsgLength(len uint32) SetMsgData(data原创 2022-05-06 15:48:49 · 1538 阅读 · 0 评论 -
使用GoLang开发游戏服务器(四)
使用GoLang开发游戏服务器(四)添加全局配置模块之前的一些端口和IP以及服务器名称等,都是写死在代码中的,我们需要增加全局配置来修改新增utils包,里面定义globalobj.go文件,用于全局配置对外提供全局var GlobalObject *GlobalObj在加载包文件时init的时候进行初始化配置文件为json的方式,进行读取type GlobalObj struct { TcpServer ziface.IServer Host string TcpP原创 2022-05-06 10:38:29 · 659 阅读 · 0 评论 -
GoLang 对于Json的操作方式
GoLang 对于Json的操作简单的将map结构的json转换为mapfunc main() { jsonStr := "{" + "\"总就业人数\": 1375.66," + "\"第一产业\": 40.83," + "\"第二产业\": 50.43," + "\"省代码\": 310000.0," + "\"省\": \"上海市\"" + "}" var f map[string]interface{} if err := json.Unmarshal([]by原创 2022-05-05 20:18:23 · 313 阅读 · 0 评论 -
使用GoLang开发游戏服务器(三)
使用GoLang开发游戏服务器(三)Request请求消息的封装定义新增IRequest接口type IRequest interface { GetConnection() IConnection GetData() []byte}新增Request结构体type Request struct { Conn ziface.IConnection Data []byte}func (r *Request) GetConnection() ziface.IConnection原创 2022-05-05 16:33:05 · 438 阅读 · 0 评论 -
使用GoLang开发游戏服务器(一)
使用GoLang开发游戏服务器(一)实现最简单的服务器和客户端的通信IServertype IServer interface { Start() Stop() Serve()}servertype Server struct { Name string IpVersion string Ip string Port int}func (s *Server) Start() { go func() { addr, err := ne原创 2022-05-04 21:05:31 · 4440 阅读 · 2 评论 -
GoLang 反射
GoLang 反射一.反射初识Go 语言提供了一种机制在运行时更新变量和检查它们的值、调用它们的方法,但是在编译时并不知道这些变量的具体类型,这称为反射机制。func main() { var x float64 = 3.1415 fmt.Println(reflect.TypeOf(x)) fmt.Println(reflect.ValueOf(x)) fmt.Println("=====================================") v := reflect.原创 2022-05-04 14:43:42 · 489 阅读 · 0 评论 -
GoLang 并发Goroutine&Channel(二)
GoLang channel通道1.channel通道初识通道是引用类型传递func main() { var ch1 chan bool ch1 = make(chan bool) go func() { for i := 0; i < 10; i++ { time.Sleep(time.Second) fmt.Println(i) } fmt.Println("结束...") ch1 <- true }() fmt.Println("chann原创 2022-05-04 09:15:57 · 166 阅读 · 0 评论 -
GoLang 并发Goroutine&Channel(一)
GoLang 并发Goroutine&Channel(一)1.Goroutinefunc main() { go printNum() for i := 0; i < 100; i++ { fmt.Println("main:", i) } time.Sleep(time.Second) fmt.Println("main Over...")}func printNum() { for i := 0; i < 100; i++ { fmt.Println("原创 2022-05-03 15:34:03 · 276 阅读 · 0 评论 -
GoLang 文件IO操作(二)
GoLang 文件IO操作(二)1.bufio包读写文件还可以使用bufio包中的方法bufio包中的方法,相比较os包中的read和write更加高效,是对os包的封装有一层缓存机制func LearnBufioMain() { file, err := os.Open("zzs.txt") if err != nil { fmt.Println(err) return } defer file.Close() reader := bufio.NewReader(file)原创 2022-05-02 19:37:26 · 478 阅读 · 0 评论 -
GoLang 文件IO操作(一)
GoLang 文件IO操作(一)1.file操作func LearnFileMain() { fileInfo, err := os.Stat("C:\\Users\\31927\\Desktop\\aa.txt") if err != nil { fmt.Println(err) return } fmt.Println(fileInfo) fmt.Println(fileInfo.Name()) fmt.Println(fileInfo.Mode()) fmt.Println原创 2022-05-02 16:23:38 · 717 阅读 · 0 评论 -
GoLang包的使用
GoLang包的使用1.包的使用事例2.init函数事例1:对于同一个go文件中,调用顺序是从上到下的,也就是说,先写的先被执行,后写的后被执行2:对于同一个包下,将文件名按照字符串进行排序,之后顺序调用各个文件中init()函数3:如果不存在依赖,按照main包中import的顺序来调用对应包中init()函数...原创 2022-05-02 08:48:52 · 546 阅读 · 0 评论 -
GoLang 基础语法(十一)
GoLang 基础语法(十一)1.错误errorfunc main() { /*f, err := os.Open("test.txt") if err != nil { fmt.Println(err) return } fmt.Println(f.Name())*/ err1 := errors.New("自己创建的错误") fmt.Println(err1) fmt.Printf("%T\n", err1) err2 := fmt.Errorf("错误码%d\n",原创 2022-05-01 18:58:12 · 178 阅读 · 0 评论 -
GoLang 基础语法(十)
GoLang 基础语法(十)1.接口嵌套func main() { var d Dog d.test1() d.test2() d.test3() var a AA var b BB var c CC a = d a.test1() b = d b.test2() c = d c.test1() c.test2() c.test3() //要实现CC接口,需要实现AA,BB接口才能使用}type Dog struct {}func (d Dog) test原创 2022-05-01 09:58:18 · 115 阅读 · 0 评论 -
GoLang 基础语法(九)
GoLang 基础语法(九)1.GoLang中的OOPfunc main() { var s1 = MyStudent{ Human: Human{name: "zzs", age: 18}, class: "一班", } fmt.Println(s1) fmt.Println(s1.age) fmt.Println(s1.name) fmt.Println(s1.class)}type Human struct { name string age int}type原创 2022-04-30 20:01:00 · 188 阅读 · 0 评论