这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。由于之前主要接触C++,所以Go基本是从零开始。下面简要总结一些Go语言的相关知识。
简介
Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。
主要有以下特点:
- 高性能、高并发
- 语法简单、学习曲线平缓
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
语法
初次接触,Go的语法接近C++语言,但是又有所不同:
-
对于变量的声明有所不同:
// (1):var name string = " " var a = "initial" var b, c int = 10, 20 // 此时声明变量的时候,一般会自动推导变量的类型。 // (2): 变量 := val f := float32(e)
- 常量的话就把上述var修改为const,但是和C++以及其他语言不同,Go没有确定的类型,需要根据上下文来自动确定类型。
- 还有很多其他语法的不同,如if else 条件语句没有括号,并且后面的执行语句必须后接大括号;不包含while,do while循环,只有for循环,这和C++也不同。
- 与C++不同的是,Go支持垃圾回收功能。Go的并行模型是以东尼·霍尔的通信顺序进程(CSP)为基础,采取类似模型的其他语言包括Occam和Limbo,但它也具有Pi运算的特征,比如通道传输。可以通过插件(Plugin)的支持,从Go中动态加载部分函数。
-
与C++相比,Go并不包括如枚举、异常处理、继承、泛型、断言、虚函数等功能,但增加了 切片(Slice) 型、并发、管道、垃圾回收、接口(Interface)等特性的语言级支持。
并且不同于Java,Go内嵌了关联数组(也称为哈希表(Hashes)或字典(Dictionaries)),就像字符串类型一样。
并且我们可使用range来快速遍历,遍历的时候对于数组会返回两个值,第一个索引,第二个对应位置的值,如果不需要索引,就用下划线来忽略。
// slice s := make([]string, 3) s[0] = "a" s[1] = "b" s[2] = "c" fmt.Println("get:", s[2]) // c fmt.Println("len:", len(s)) // 3 // map m := make(map[string]int) m["one"] = 1 m["two"] = 2 fmt.Println(m) // map[one:1 two:2] fmt.Println(len(m)) // 2 fmt.Println(m["one"]) // 1 fmt.Println(m["unknow"]) // 0 // range nums := []int{2, 3, 4} sum := 0 for i, num := range nums { sum += num if num == 2 { fmt.Println("index:", i, "num:", num) // index: 0 num: 2 } } fmt.Println(sum) // 9并且我在实际操作中,还出现了一些其他错误,总结如下:
- 每行程序结束后不需要撰写分号(;)。
- 大括号({)不能够换行放置。
- if判断式和for循环不需要以小括号包覆起来。
-
函数编写也和C++等其他语言不同,变量类型是后置的;并且支持返回多个值,如第一个是真正的返回结果,第二个是错误信息。
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
func main() {
v, ok := exists(map[string]string{"a": "A"}, "a")
fmt.Println(v, ok) // A True
}
- GO虽然支持指针,但是和C++相比支持的操作很有限,主要对传入参数进行修改。
- 结构:是用户定义的类型,表示字段的集合。它可以用于将数据分组为一个单元而不是将它们中的每一个作为单独的值的地方。
type Employee struct {
firstName string
lastName string
age int
}
上面的代码片段声明了一个Employee的结构类型。结构体变量的成员可以通过点操作符访问,比如Employee.firstName和Employee.lastName。因为Employee是一个变量,它所有的成员也同样是变量,我们可以直接对每个成员赋值,或者是对成员取地址,然后通过指针访问。