『Go』浅谈 Go 与 C/C++ 语法的不同
看了这么多教程,感觉还是Go 语言之旅最适合新手
本周初学 Go 的基本语法,总结了一下和 C/C++ 的区别
Go 语法与 C/C++ 的不同 (浅谈)
-
每句话之后不一定要分号了
-
引用了包,或者变量声明没有用,就不能成功编译
-
大括号强制使用 C 风格:不换行,不能使用 C++ 风格
-
Go 的变量声明方面,名称在前,类型在后:
1
2
3
4var a int // 声明一个变量,默认为0,这和C/C++不一样
var b = 10 // 声明并初始化,且自动推导类型
c := 20 // 初始化,且自动推导(只能在函数里用)
然后少了一个 char 类型,多了复数
-
Go 的 for 语句后面的三个构成部分外没有小括号, 大括号 { } 则是必须的(if同理)
-
没有了While,可以用for代替:
1
2
3
4
5
6
7func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
} -
Go的 switch 不需要 break,并且 switch 的 case 无需为常量,且取值不必为整数
-
defer 语句会将函数推迟到外层函数返回之后执行。推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用。可以defer多个函数,推迟的函数调用会被压入一个栈中。当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。
1
2
3
4
5
6package main
import "fmt"
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}适用场景:释放资源(免得忘记了)、处理panic(把判断程序非正常关闭的处理写在defer里)
-
没有了 --i、++i,i–、i++等也只能单独使用,不能在表达式里面用了
-
浮点数不能直接比较,采用下面的方案:
1
2
3
4
5func isEqual(f1,f2,p float64) bool {
// p为用户自定义精度,如:0.00001
return math.Abs(f1-f2) < p
} -
字符串是只读的,修改要借助于 [ ]byte 或切片
-
长度是数组类型的一部分,[3]int与[4]int是不同的类型
-
当把一个数组作为参数传入函数的时候,传入的其实是该函数的副本,而不是他的指针
-
要导出的元素(函数、变量等)首字母大写
-
“类型定义”和“类型别名”的区别
1
2
3
4
5
6
7
8type MyInt int // 类型定义
type AliasInt = int // 类型别名,支持使用括号,同时起多个别名
var a1 MyInt
fmt.Printf("a1 type: %T\n", a1) //main.MyInt
var a2 AliasInt
fmt.Printf("a2 type: %T\n", a2) //int -
新增了切片类型,切片就像数组的引用,更改切片的元素会修改其底层数组中对应的元素
-
用 make 创建切片
切片可以用内建函数 make 来创建,这也是你创建动态数组的方式。
make 函数会分配一个元素为零值的数组并返回一个引用了它的切片:
1
a := make([]int, 5) // len(a)=5
要指定它的容量,需向 make 传入第三个参数:
1
2
3
4b := make([]int, 0, 5) // len(b)=0, cap(b)=5
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4 -
指针无法运算
-
结构体指针指示层级关系时直接用’.‘,而不是用’->’
-
当从映射中读取某个不存在的键时,结果是映射的元素类型的零值
-
函数声的格式不一样:
1
2
3
4func 函数名字 (参数列表) (返回值列表){
// 函数体
return 返回值列表
} -
不支持默认参数
-
多了个匿名函数
-
类型转换不一样:T(v) 将值 v 转换为类型 T ,并且Go 在不同类型的项之间赋值时需要显式转换
-
函数可以作为变量直接传入到函数里
(套娃警告) -
函数可以作为函数的返回值(称为 闭包)
-
方法 声明方式不一样:在函数声明时,在其名字之前放上一个变量,即是一个方法。这个附加的参数会将该函数附加到这种类型上,即相当于为这种类型定义了一个独占的方法。