01.Go语言实战——介绍
Go 语言开发团队花了很长时间来解决当今软件开发人员面对的问题。开发人员在为项目选择语言时,不得不在快速开发和性能之间做出选择。C 和 C++这类语言提供了很快的执行速度,而 Ruby 和 Python 这类语言是擅长快速开发。Go 语言在这两者之间架起了桥梁,不仅提供了高性能的语言,同时也让开发更快速。
1、开发速度
Go 语言使用了更加智能的编译器,并简化了解决依赖的算法,最终提供了更快的编译速度。编译 Go 程序时,编译器只会关注那些直接被引用的库,而不是像 Java、C 和 C++那样,要遍历依赖链中所有依赖的库。因此,很多 Go 程序可以在 1 秒内编译完。在现代硬件上,编译整个 Go 语言的源码树只需要 20 秒。
2、并发
Go 语言对并发的支持是这门语言最重要的特性之一。goroutine 很像线程,但是它占用的内存远少于线程,使用它需要的代码更少。通道(channel)是一种内置的数据结构,可以让用户在不同的 goroutine 之间同步发送具有类型的消息。这让编程模型更倾向于在 goroutine 之间发送消息,而不是让多个 goroutine 争夺同一个数据的使用权。
2.1、goroutine
goroutine 是可以与其他 goroutine 并行执行的函数,同时也会与主程序(程序的入口)并行执行。在其他编程语言中,你需要用线程来完成同样的事情,而在 Go 语言中会使用同一个线程来执行多个 goroutine。
2.2、通道
通道是一种数据结构,可以让 goroutine 之间进行安全的数据通信。通道可以帮用户避免其他语言常见的共享内存访问的问题。
并发最难的部分就是要确保其他并发运行的进程、线程或 goroutine 不会意外修改用户的数据。当不同的线程在没有同步保护的情况下修改同一个数据时,总会发生灾难。在其他语言中,如果使用全局变量或者共享内存,必须使用复杂的锁规则来防止对同一个变量的不同步修改。
为了解决这个问题,通道提供了一种新模式,从而保证并发修改时的数据安全。通道这一模式保证同一时刻只会有一个 goroutine 修改数据。通道用于在几个运行的 goroutine 之间发送数据。
需要强调的是,通道并不提供跨 goroutine 的数据访问保护机制。如果通过通道传输数据的一份副本,那么每个 goroutine 都持有一份副本,各自对自己的副本做修改是安全的。当传输的是指向数据的指针时,如果读和写是由不同的 goroutine 完成的,每个 goroutine 依旧需要额外的同步动作。
3、Go 语言的类型系统
Go 语言提供了灵活的、无继承的类型系统,无需降低运行性能就能最大程序上复用代码。这个类型系统依然支持面向对象开发,但避免了传统面向对象的问题。Go 开发者使用组合(composition)设计模式,只需简单地将一个类型嵌入到另一个类型,就能复用所有的功能。其他语言也能使用组合,但是不得不和继承绑在一起使用,结果使整个用法非常复杂,很难使用。在 Go 语言中,一个类型由其他更微小的类型组合而成,避免了传统的基于继承的模型。
另外, Go 语言还具有独特的接口实现机制,允许用户对行为进行建模,而不是对类型进行建模。在 Go 语言中,不需要声明某个类型实现了某个接口,编译器会判断一个类型的实例是否符合正在使用的接口。Go 标准库里的很多接口都非常简单,只开放几个函数。
3.1、类型简单
Go 语言不仅有类似 int 和 string 这样的内置类型,还支持用户定义的类型。在 Go 语言中,用户定义的类型通常包含一组带类型的字段,用于存储数据。Go 语言的用户定义的类型看起来和 C 语言的结构很像,用起来也很相似。不过 Go 语言的类型可以声明操作该类型数据的方法。
3.2、Go 接口对一组行为建模
接口用于描述类型的行为。如果一个类型的实例实现了一个接口,意味着这个实例可以执行一组特定的行为。Go 语言的接口更小,只倾向于定义一个单一的动作。实际使用中,这更有利于使用组合来复用代码。
4、内存管理
Go 语言拥有现代化的垃圾回收机制,虽然 Go 语言的垃圾回收会有一些额外的开销,但是编程时,能显著降低开发难度。Go 语言把无趣的内存管理交给专业的编译器去做,而让程序员专注于更有趣的事情。
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
-
Go 语言是现代的、快速的,带有一个强大的标准库。 -
Go 语言内置对并发的支持。 -
Go 语言使用接口作为代码复用的基础模块。
推荐阅读 |
---|