Go语言学习心得

Posted SEATELL海说软件

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言学习心得相关的知识,希望对你有一定的参考价值。


-海说软件接受各种技术咨询及开发业务-


Go语言学习心得




       17年接触 golang,虽然早就听说 golang 并发能力强、跨平台无虚拟机、自动 GC、快速编译等特点,但实际去练习和使用它却没有多长时间。虽然如此,感觉还是学到了点东西。


记得最早对 golang 印象还在上大学, 那时 golang 给我的印象是好像类似 lua,整个程序就只有一个线程,想要并发得靠协程间来回切换,因为当时还不够懂异步 IO,所以感觉这还不如用线程、线程池,而 lua 那种协程没发并行计算,是 1个线程对应 N 个协程,如果一个协程有个死循环整个线程会卡住,其他协程就不能执行了,因此产生了对 golang 的误解。


后来学习 nodejs 了解到了异步 IO,再后来又去看了协程异步 IO 库 state-threads 的机制,最后阅读了 golang 底层实现的相关资料,才解开了之前的误解并清楚的认知到这种并发方式的高效,M 个线程对应 N 个协程加上异步 IO 并依靠调度器,的确能提供很高的并发效率。不过虽然底层是异步 IO,但 golang 通过调度器让用户层还是原来阻塞式的写法,相对于如 libev,libuv 这类的回调函数式风格的异步 IO 框架, 较符合人们的编程习惯,提高了性能又不失开发效率。

  

接下来介绍下这门语言的一些特点:


1、内建的并发原语


Golang 在语言层面对并发编程提供支持,一种类似协程,称作 goroutine 的东东,只需在函数调用语句前添加 go 关键字,就可创建并发执行单元。开发人员无需了解任何执行细节,调度器会自动将其安排到合适的系统线程上执行。  

goroutine 是一种非常轻量级的实现,可在单个进程里执行成千上万的并发任务。另有与之配套的 chan 类型,用以实现 "以通讯来共享内存" 的 CSP 模式,廉价的 goroutine 可以让我们美滋滋地处理异步任务,chan 可以用来交换数据, 这些简化了原本复杂的并发开发方式。

例子:

var channel chan int = make(chan int)
 func asyncIO(){
  
fmt.Println("aab")
  
channel<-666
 
}
 
func mian(){
  
go asyncIO()
  
fmt.Println("main")
  
fmt.Println(<-channel)
 }

 

输出:

main

aab

666


2、没有类和继承


 Go语言没有类和继承的概念,取而代之的是 struct、interface 和方法,所以它和 Java 或 C++ 看起来并不相同。但是它通过接口(interface)的概念来实现多态性,interface 的特性是 golang 支持鸭子类型的基础,即“如果它走起来像鸭子,叫起来像鸭子(实现了接口要的方法),它就是一只鸭子(可以被赋值给接口的值)”。凭借接口机制和鸭子类型,golang 提供了一种游离于类、继承、模板之外的另一种可靠的选择。


例子:

type Duck interface {
  
cry()
  
walk()
 }
 
type Goose struct {
 }

 
func (g Goose) cry() {
  
fmt.Println("嘎嘎嘎")
 }
 
func (g Goose) walk() {
  
fmt.Println("< < < <")
 }

 
type Actors struct {
 }

 
func (a Actors) cry() {
  
fmt.Println("嘎 嘎 嘎")
 }
 
func (a Actors) walk() {
  
fmt.Println("< <  < <")
 }

 
func main() {
  
var duck Duck
  
duck = new(Goose)
  
duck.cry()
  
duck.walk()
  
duck = new(Actors)
  
duck.cry()
  
duck.walk()
 }

 

输出:

嘎嘎嘎

< << <

嘎 嘎 嘎

<<  < <


3、不用trycatch来处理异常


  Java、javascript 这类是通过 try 块来包裹住会抛出异常的代码,catch 块来处理捕获的错误,而 go 语言就不一样了,是通过 panic 函数来抛出,而捕获则需要 defer +  recover, 不过这个 defer 不是 block 级别的,而是函数级别的,需要在函数返回前才得到执行。怎么说呢,这种机制不同于以上两种语言,各有各的特点,不过 golang 的就和 nodejs 以前的异步操作的回调函数一样,错误处理比较繁琐,需要对很多 err 进行判断。


例子:

func error1(){
  
defer func(){
     
if err:=recover; err!=nil{
        
fmt.Println(err)
      }
   }()
  
panic("aab")
  
fmt.Println("hihihi")
 }
 
func main(){
  
error1()
  
fmt.Println("main")
 }

 

输出:

aab

main


以上就是 golang 感觉比较有特点的地方。总的来说呢,golang 是比较容易上手,学习曲线也比较低,最好是有 c 或 c++ 基础,因为 golang 里面有指针之类的东西,有前两个的基础理解较为方便。还有对于运维来说,Go 编译生成的是一个静态可执行文件,除了 glibc 外没有其他外部依赖。这让部署变得很方便,不需要操心应用所需的各种包、库的依赖关系,减轻了维护的负担。


当然 golang 也有一些不足之处,不过自己只拿来写过的练手 web 服务不便谈论,golang 其他优秀的、好玩的特性,因为篇幅限制,就不一一阐述了,欢迎大家转发、点赞、评论,谢谢。


海说软件会持续推出前端教学课程、技术干货。

往期课程:


















-END- 

以上是关于Go语言学习心得的主要内容,如果未能解决你的问题,请参考以下文章

你知道的Go切片扩容机制可能是错的

Javalucene4.0学习心得

golang代码片段(摘抄)

[Go] 通过 17 个简短代码片段,切底弄懂 channel 基础

解决go: go.mod file not found in current directory or any parent directory; see ‘go help modules‘(代码片段

windows通过Visual Studio Code中配置GO开发环境(转)