Go语言基础学习与认识 | 青训营

131 阅读7分钟

计算机软件经历了数十年的发展,形成了多种学术流派,有面向过程编程、面向对象编程、函数式编程、面向消息编程等,这些思想究竟孰优孰劣,众说纷纭。

除了OOP外,近年出现了一些小众的编程哲学,Go语言对这些思想亦有所吸收。例如,Go语言接受了函数式编程的一些想法,支持匿名函数与闭包。再如,Go语言接受了以Erlang语言为代表的面向消息编程思想,支持goroutine和通道,并推荐使用消息而不是共享内存来进行并发编程。总体来说,Go语言是一个非常现代化的语言,精小但非常强大。 Go语言的设计理念和优势使它的定位非常明确,它适合做:网络编程,服务器编程,分布式系统,数据库系统,云平台。

Go在语法上具备如今大多数主流语言的特点,但又有其独特之处。 比如struct、interface、slice、map、channel的设计特点,比如保留指针但弱化指针的概念并简化用法,比如“零值”的设定,比如switch case不需要break改提供通常不用的fallthough,比如语法级别支持并发任务编程的Goroutine,等等。有变方便的地方,也有变更麻烦的地方,很多具体细节是需要在实际使用中才能深切体会到的。

有句“大实话”:Go代码里有一半的代码量是用来写“if err != nil {}”的!如果你第一次接触到这样的错误处理方式,没有try/catch(except),只有“if err != nil {}”和defer/panic/recover,你可能会感到很抓狂!其实Swift方式的“guard ... else {}”与Go方式的“if err != nil {}”有异曲同工之妙,同样都是“获取某值,值异常则立即做异常处理,否则正常继续”的思路,不同的是Swift方式含义更明确一些,通用性更高一些;而Go这边,通常是函数或者方法设计了多返回值(通常是双返回值),并且约定最后一个值用来返回错误对象,然后才有利用if判断的“if err != nil {}”这种看起来挺蹩脚的写法。

对比之下,Swift方式看起来显然更为优雅,而Go方式这样的设计,觉得可能是为了避免添加太多的语法糖导致增加语言的复杂性吧,“简洁至上”。

正因如此,当你初入Go语言时,总会有一些特性让你感觉很不理解,或者很不习惯。

如果你原本的编程基础是零,即完全没有基础,那么Go并不会是你的入坑首选。 因为Go不像Python能隐藏绝大部分初学者需要花时间理解的枯燥的基础知识,而且在第三方模块上,对比丰富的Python PyPI模块仓库,Go第三方包数量目前还比较有限,光这两点就已经无法做到完完全全的“开箱即用”了,很容易让人劝退;也因为,只有尝尽C、Java等其他你接触过的语言的“苦”,才能体会到Go语言带来的“甘”。零基础的你,培养编程兴趣毋庸置疑推荐从Python开始。

如果你原来恰好是一位Pythoner,那上手Go来就会觉得处处受限! 明明一两个Python语句可以表达清晰的,为什么需要写这么多呢?Python就算加上“typing/type hints(类型注解)”,也不至于很“啰嗦”的呀。此时面对Go,你需要有足够多的耐心,一点一滴地学习和尝试,逐渐地,逐渐地,会感受到Go强大的代码规范器可以在编译前帮你排查绝大多数的低级错误或者潜在错误,如此一来对比完全允许用户自由发挥的Python开发过程,Go必然使你对自己写出来的程序稳定性信心倍增,不是吗?

如果你原来恰好接触过TypeScript、Swift等其他语言,会发现它们之间既有共同之处,又有大不同。 比如TS的interface概念就与Go语言相似,都是以“鸭子类型”思想为基础的产物。Go通过定义interface对具体类型的方法行为进行抽象,利用struct结构体标签推断数据对象的内部结构;类似地,TS通过定义interface的结构,就可以用它来推断object的结构及其方法行为,兼容性比Go高,没有Go那么严格的程度(可能这样更适应网页应用开发)。Swift 4.0新增的Codable也有异曲同工之妙,但主要用于推断数据对象的结构,方便数据的序列化和反序列化的操作,它没有推断方法的作用。

上面提到的“相似”只是冰山一角,利用语言间相似之处可以帮助我们快速上手熟悉新接触的语言,毕竟目前各大主流程序语言都会汲取其他语言的优点融入到自身之中,让自己变得更加强大。

尽管Go语言有强类型要求,尽管有着初学者一时半会难理解参透的struct、interface,但个人感觉Go的实现,已经试图在用户体验和鲁棒性之间寻找最佳平衡点。比如“:=”(声明并赋值)可以隐藏掉大部分的变量类型声明,“go func”就可以轻松实现并行任务的需求,以及神奇的struct结构体标签与Unmarshal(),等等。“严格的”Go相比“自由的”Python,编写高质量代码的过程可能会更加艰难,但这种“艰难”只会是暂时的,尤其是在持续型的项目中,不管是前期开发还是后期维护,优势便会逐渐显现出来。

基础

项目工程的路径为:D:\develop\Go\workspace,要先把这个路径添加到环境变量GO_PATH里。代码放在项目路径下的src\go_code\src\project01目录里

helloworld

go语言的helloWorld如下:

package main
 
import "fmt"
 
func main()  {
    fmt.Println("szc")
}

main函数必须在main目录下,包名则必须和上级目录名一致(main);一个项目必须有且只有一个main目录(或main包)

go程序既可以直接运行

image.png

亦可以先编译,再运行

image.png

三种声明方式

package main

import "fmt"

func main() {
    var i int  = 10 // var 变量名 类型 = 值
    var j = 1.2 // var 变量名 = 值

name := "szc" // 变量名 := 值,自动推导类型

fmt.Println("i = ", i, ", j = " , j , ", name = ", name)
}

一次声明多个变量,变量名和值一一对应

var a, sex, b = 1, "male", 7

也可以这样

a, sex, b := 2, "male", 4

函数外声明全局变量

var (
n1 = 1
n2 = 2
n3 = 3
)

var n4 = "n4"

func main() {
fmt.Println("n1 = ", n1, ", n2 = ", n2, "n3 = ", n3, ", n4 = ", n4)
}

变量声明后必须使用,而且不能隐式改变类型(int转float)

计算机软件经历了数十年的发展,形成了多种学术流派,有面向过程编程、面向对象编程、函数式编程、面向消息编程等,这些思想究竟孰优孰劣,众说纷纭。

除了OOP外,近年出现了一些小众的编程哲学,Go语言对这些思想亦有所吸收。例如,Go语言接受了函数式编程的一些想法,支持匿名函数与闭包。再如,Go语言接受了以Erlang语言为代表的面向消息编程思想,支持goroutine和通道,并推荐使用消息而不是共享内存来进行并发编程。总体来说,Go语言是一个非常现代化的语言,精小但非常强大。