最近两天对go语言做了一个初步的了解,记录一下。之前没有按照原创发表,所以重新发布一次。
第一个感受就是使用起来方便,从官网下载安装包,参考https://golang.google.cn/doc/install,解压到/usr/local/go目录,然后将go目录下的bin目录添加到环境变量即可export PATH=$PATH:/usr/local/go/bin,最后运行go version查看是否生效,编写一个简单的go文件,直接go run hello.go即可运行起来了。
如果要使用vscode进行调试也非常方便,安装go相关的插件即可(ctrl+shift+p,输入go:install),注意开国内代理go env -w GOPROXY=https://goproxy.cn。然后在main函数的那个文件按F5就可以调试了,可以打断点看堆栈变量的值,我是用的wsl2配的centos7,体验很不错。
学习过c/c++后,对go的学习就更加容易了,很多基本都是c相关的语法,增加了一些新特性,比如gc,goroutine协程,channel通道,对于高并发编程更加方便,一个协程类似于用户态轻量级现场,采用go加函数名的方式运行,在一个协程里面可以通过channel的方式将值传到另外的协程,channel类似于管道的概念,这样多个协程直接就可以通信了。
go语言编程时对格式有要求,比如左花括号不能换行,vscode保存时会自动格式化代码,看起来还是很清爽的。
注意go没有继承的概念,但可以实现面向对象的多态,主要是通过interface的方式,只要某个struct实现了该interface里面的所有方法,就可以将该struct看作该interface的具体实现,类似于java里面的implement,只是省略了该关键词,对该方法就可以实现多态调用,即定义变量用interface类型,实例化为某个struct类型,该变量调用interface的方法其实就是调用interface的实现的方法了。这里的interface其实类似于c++里面的抽象类,抽象类里面只给方法,不给具体实现,由继承的子类来完成实现,一个struct可以实现多个interface的接口,相当于多重实现了。
但go可以通过组合的方式实现伪继承,直接在struct里面写上需要基础的struct的名字,这个struct的变量和成员就继承下来了,写多个struct的名字,就相当于c++里面的多重继承了,如果子类和父类有相同的成员,调用时优先选择子类的,如果子类没有,而多个父类有相同的成员,那调用时就需要指定是哪一个父类,否则就报错了。
至于封装特性,可以将package下面go文件里面的struct名字以小写字母开头,这样就是私有的了,struct里面的成员也以小写字母开头,如果要public属性,就已大写字母开头,然后写一个new的方法,该方法以大写字母开头,这样就是公有的了,类似于c++里面的构造函数,如果要访问或者改写struct里面的私有成员 就可以写一个以大写字母开头的set/get函数,这样就可以在包外调用了,这里是权限访问主要是通过大小写开头来控制的,省略了public和private的关键词。
go采用package的方式进行工程管理,包名一般为文件夹的名字,文件夹下面有很多go源文件,一个包名类似于cpp里面的namespace,如在一个go文件中要使用另外一个包里面的成员,就需要在文件头加入import,比如import “fmt”,这个fmt就是标准库的一部分,目前go的标准库比较丰富,很多功能直接接入标准库即可完成,类似于python,减少了很多造重复轮子的代码量。
另外一个要说的是,c++和java都有异常处理的机制,抛出异常后catch,go也有这样的机制,只是名字不一样,go通过panic抛出error信息,通过recovery()捕获错误,一般将recovery放在defer中,一个函数中可以有多个defer,是以栈的方式存储,函数退出时反向调用defer,相当于出栈,所以可以在defer里面捕获错误,这个defer有点类似java里面的finally。go对有返回error的函数必须处理其错误,除非该函数的返回值也不考虑,就可以不处理error。
- 本文作者: nephen
- 本文链接: golang初探 | Nephen's Blog
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!