Go是一种相对较新的语言,由Google的Robert Griesemer,Rob Pike和Ken Thompson于2009年之前创建。它是开源的,因此任何人都可以为此做出贡献并提出新功能。
替代C ++似乎主要是为了使Google的软件工程师的工作更轻松。 它针对系统编程,例如云系统,分布式系统和微服务。
一些特点
Go是静态类型的。 所有变量都需要使用给定类型声明。 bool,string和" number"(int,uint,float64,complex128等)类型是基本类型。 然后,也可以声明结构(就像在C中一样)。 这对于在编译时检测错误很有帮助。 哦,顺便说一句,Go是一种编译语言。
Go代码编译非常快! 这是创建者试图改进的有关C和C ++的关键方面之一,他们做到了! 此外,由于代码直接编译为机器代码,因此执行时间非常快。 这也使可执行文件高度可移植到具有相同平台的其他计算机上。
Go有接口。 对于面向对象的程序员,这可能有点令人失望,但是Go没有类。 它不支持继承。 但是,它确实支持结构的创建以及为它们的方法的定义。 此外,它支持接口的定义,该接口支持松散耦合的系统。 还有一件很酷的事情是,您可以定义一个空接口(interface {}),然后将声明一个通用对象!
Go专注于处理错误。 Go不支持例外。 它的哲学是函数必须返回返回值(或多个值,因为它可以同时返回多个变量)和错误值。 这使开发人员可以考虑发生故障时该怎么办。 但是,还有一些与例外类似的东西,即"恐慌"和"恢复"机制。
去有垃圾收集。 这是对C和C ++的重大改进。 它是一种非常有效的语言,它增加了大多数最近使用的语言所具有的非常有用的功能。
Go支持内置并发。 到目前为止,这是Go语言最酷的功能! 它非常有效且易于使用。 我们将在下一节中详细说明。
Go中的并发
首先,让我们区分并发和并行。 并发是关于同时但不一定同时执行的独立进程。 并行意味着执行是同时的。 因此,并行化只能通过多个内核来实现,而并发只能通过正确调度不同的进程在一个内核上完成。 Go实现了非常高效的并发性,并且还支持并行性。
人们认为Go遵循参与者模型的并发性。 在此模型中,参与者是计算的原始单位。 接收消息并根据消息进行某种计算的东西。 他们获得输入,执行操作并提供输出。 Go中的演员是goroutines。
角色完全相互隔离。 这意味着它们不共享内存,而是通过其他结构进行通信,从而为它们提供同步。 Go为此实现了渠道。 即使可以通过不同的goroutine来使用共享内存结构,使用通道也可以使并发真正容易且安全。
最好的部分是goroutines非常轻巧。 Go计划在系统线程上执行goroutine,从而允许多个goroutine在单个OS线程上同时运行。 这样做的好处是减少了例程的堆栈(与OS线程的1MB相比,减少了4KB),并节省了OS线程之间的上下文切换成本,这比在goroutine之间切换要大得多。 我们甚至可以以非常低的成本同时运行数十万个goroutine!
我们还提到过,在go中使用并发很容易。 让我们看一个例子!
- package main
- import “fmt”func add_string(string_to_add string, input_ch chan string, output_ch chan string) {
- fmt.Println(“Running: add_string”) result_string := <-input_ch + string_to_add output_ch <- result_string}func initialize_string(initial_string string, input_ch chan string) {
- fmt.Println(“Running: initialize_string”) input_ch <- initial_string}func main() {
- input_ch := make(chan string)
- output_ch := make(chan string)
- go add_string(“Hello World!”, input_ch, output_ch)
- go initialize_string(“”, input_ch)
- fmt.Println(“Waiting for goroutines”)
- fmt.Println(<-output_ch)}
运行此代码后,输出为:
- Waiting for goroutines
- Running: initialize_string
- Running: add_string
- Hello World!
因此,在这里我们看到运行并发的go例程有多么容易。 只需定义一个函数并在调用它之前添加" go"即可。 就这么简单! 这将安排goroutine,但调用者函数的执行将继续。 在这种情况下,我们调用该函数以添加" Hello World!"。 第一。 然后是初始化函数,然后我们打印消息" Waiting for goroutines",但控制台显示了不同的打印消息顺序。 为什么?
如前所述,为了同步goroutine,我们可以使用通道。 我们首先创建一个输入通道和一个输出通道,然后以以下方式使用它们。 add_string函数将等待,直到输入通道中有内容为止。 然后我们调用该函数以空字符串初始化输入通道。 但是,主函数继续执行并显示" Waiting for goroutines"。 然后,它等待输出通道中包含某些内容。 这将允许初始化函数将空字符串放入输入通道。 add_string函数将唤醒并添加" Hello World!"。 到输出通道,然后主功能将再次唤醒并最终打印完整的消息。 容易吧?
Go在哪里使用?
Go用于开发许多您可能知道的解决方案,例如Google,YouTube,Soundcloud,Docker等。但是,在Worldsensing中使我们开始了解Go的一种是Chirpstack。 这是一个开源的LoRaWAN网络服务器堆栈。 它提供了一个用于设备管理的Web界面,并提供了许多方法来集成其他应用程序,例如API,MQTT队列等。它具有模块化的体系结构,如您所见。
Chirpstack是可配置的,并且易于部署。 您甚至可以找到带有docker-compose.yml文件的开源项目,该文件可以轻松启动所有内容!
如您所见,Go等出色的语言使开发人员可以创建出色的项目。