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

    原文作者:SEATELL海说软件
    原文地址: https://www.jianshu.com/p/58b20cec27f5
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞