Java转go
没办法,为了混口饭吃,该转还是得转,人在屋檐下~
总的来说,go语言在设计和框架上更为简洁轻量。
go源码中文网站:https://studygolang.com/pkgdoc
go hello world
和java一样,go也有自己的sdk,通过https://go.dev/进行下载安装,会自动配置好环境变量。
GOROOT是go命令的可执行文件所在目录。GOPATH现在已经作废,最新的官方依赖管理工具是go module,类似Java中的maven和gradle。
两个命令:
|
|
|
|
变量
go语言变量声明方式:
|
|
下面是const常量,具备只读属性:
|
|
函数
和java函数不同:
1.go方法返回值支持多个
2.在参数和返回值上,都是变量名在前,类型在后
3.java函数返回值在函数名前,go函数返回值在最后
常见写法:
|
|
包管理
go之前使用GOPATH,强制项目源代码放在GOPATH下…且没有依赖版本控制概念,无法指定版本号维护依赖…
现行的依赖管理模式是go module
包的加载顺序,采取递归形式调用,优先加载常量和变量,再执行每个包的init函数(需要显式定义,否则不执行)

包中的函数,通过函数名首字母大小写控制包外是否可见
例子:
|
|
指针
基本类型值传递与指针传递:
|
|
defer
类似java中的finally,不同的是defer作用于函数,finally一般与try catch搭配使用
|
|
Slice
一般开发过程中不用数组
数组和变长数组Slice,语法是[]int,和java相反
数组遍历、传参:
|
|
切片是引用传递
|
|
切片声明和判空:
|
|
切片追加操作,len为当前长度,capacity为最大容量
|
|
切片截取操作:普通截取为指针赋值,不涉及元素深拷贝。若要将底层数组也拷贝到新切片,则需要copy:
|
|
map
map判空和slice同理,声明方式如下:
|
|
map的各种操作:
|
|
面向对象
type关键字:声明一种类型
结构体
对标java的类,通过结构体声明变量名首字母控制可见性(封装)
结构体声明和传参操作:
|
|
继承
语法比较清奇,只需要写一个结构体名:
|
|
多态
interface实现,需要实现结构体绑定全部接口方法,才算实现该接口
|
|
interface
interface分为iface和eface,在sdk的runtime包中。
eface是空接口,即代码中的interface{},包含类型和实例数据:

|
|
任何类型都可以赋值给interface{}空接口,此时要注意其类型为:

这个类型还是interface{},而不是string,如果要使用string值,可以进行断言。
反射
在计算机学中,反射是指计算机程序在运行时(runtime)可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是程序在运行的时候能够 “观察” 并且修改自己的行为(来自维基百科)。
反射能够带来的能力有:
1.一套代码能够操作任意类型的对象
反射具体代码:
|
|
结构体标签
给结构体变量绑定多个标签,目前见过的例子有json的序列化字段名
通过反射获取结构体标签:
|
|
json中的结构体标签:
|
|
goroutine
协程是比线程更轻量级的运行单元
GMP模型相关:
https://go.cyub.vip/gmp/gmp-model/
https://learnku.com/articles/41728
goroutine创建执行:
|
|
匿名函数方法创建和执行协程:
|
|
channel
两个协程之间的通信机制
1.无缓冲的channel:谁先到谁阻塞,直到完成对接,双方释放。
|
|
2.有缓冲的channel:当channel有元素时随放随拿,当channel满时,再往里写数据会阻塞;当channel为空,从里面取数据也会阻塞。
|
|
channel开关控制:
|
|
往关闭之后的channel发数据,会报panic;但关闭后还能从channel接收数据
channel的select操作:
|
|
select关键字是专门针对管道操作,和switch无关。
能够让当前goroutine同时等待多个channel可读或可写,当任意一个ready时立刻执行该case,若同时多个case都ready,会随机选择一个执行。