基础知识
Go语言就是为了解决编程语言对并发支持不友好、编译速度慢、编程复杂这三个问题而诞生的
特点:
- Go语言选择组合思想,抛弃继承关系
- 通过接口组合,自由组合成新接口,用接口实现层与层之间的解耦
语言特性对比:
package main
import "fmt"
func main() {
fmt.Printf("Hello world")
}
Go源代码特性解读:
- 源代码以.go为后缀
- 源程序默认为UTF-8编码
- 标识符区分大小写
- 语句结尾的分号可以省略
- 函数以func开头,函数体开头的“{”必须在函数头所在行尾部,不能单独起一行
go build hello.go //编译
./hello //运行
token:关键字、标识符、操作符、分隔符、字面常量
关键字(25个):
package、import、const、var、func、go、return、struct、interface、map
if else、for range break continue、switch select type case default fallthrough、goto
defer //延迟执行关键字
go //并发语法糖关键字
chan //通道类型关键字
内置函数:
make、new、len、cap、append、copy、delete、panic、recover、close、complex、real、image、print、println
常量值标识符:
true,false、inta(连续枚举类型的声明中)、nil
变量:
var varName dataType [ = value]
varName := value
常量:
const {
c0 = iota // c0 == 0
c1 = iota // c1 == 1
c2 = iota // c2 == 2
}
const{
c0 = iota
c1
c2
}
基本数据类型:
布尔类型:bool
整型:byte、int、int8、int16、int32、int64、unit、unit8、unit16、unit32、unit64、uintptr
浮点型:float32、float64
复数:complex64、complex128 (var v= complex(2.1,3) a:=real(v) b:=image(v))
字符:rune
(Go 内置两种字符类型 (1)byte字节类型 (2)unicode 编码字符rune。
rune是go内部是int32类型的别名,占用4个字节)
字符串:string (b:= []byte(a) //切片 b:=a[0:4])
错误类型:error
* pointerType
[n] elementType
[] elementType
map [keyType] valueType
chan valueType
指针:
var a = 11
p := &a
Go由于支持垃圾回收,如果支持指针运算,会给垃圾回收的实现带来很多不便
函数中允许返回局部变量的地址,使用“栈逃逸”机制将这种局部变量的空间分配在堆上
func sum(a,b int) *int {
sum:=a+b
return &sum //sum会分配到heap上
}
数组:
a:=[3]int{1,2,3}
a:=[...]int{1,2,3}
a:=[3]int{1:1,2:3}
a:=[...]int{1:1,2:3}
数组的特点:
- 数组创建完长度就固定了,不可能再追加元素
- 数组是值类型的,数组赋值或作为函数参数都是值拷贝
- 数组长度是数组类型的组成部分,[10]int 和 [20]int 表示不同的类型
- 可以根据数组创建切片
a:=[...]int{1,2,3}
b:=a[0]
for i,v:= range a {
}
alength :=len(a)
for i:=0;i<alength;i++{
}
切片:
变长数组,其数据结构中有指向数组的指针,所以是一种引用
- 底层数组的指针
- 切片的元素数量
- 底层数组的容量
切片的创建:
- 由数组创建
- 通过内置函数make创建切片
a:=make([]int,10)
b:=make([]int,10,15)
切片支持的操作:
- 内置函数len()返回切片长度
- 内置函数cap()返回切片底层数组长度
- 内置函数append()对切片追加元素
- 内置函数copy()用于复制一个切片
map:map[K]T
Go内置的map不是并发安全的,并发安全的map可以使用标准包sync中的map
mp:=make(map[int]string)
mp[1] = "tom"
mp[2] = "pony"
delete(mp,3)
struct
- struct结构中的类型可以是任意类型
- struct的存储空间是连续的,其字段按照声明时的顺序存放
struct {
FieldName FieldType
}
type TypeName struct{
FieldName FieldType
}
示例:
type Person struct{
Name string
Age int
}
type Student struct {
*Person
Number int
}
a:=Person{"Tom",21}
p:= &Person{
Name:"tata",
Age:12,
}
s:= Studnet{
Person:p,
Number:110,
}
if语句
- 判断子句不需要用小括号括起来
- if后面可以带一个简单的初始化语句,并以分号分割,该简单语句声明的变量的作用域是整个if语句块
- if分支语句遇到return后直接返回
if err,file:=os.Open(“xxxxx”);err == nil {
......
}else{
return nil,err
}
switch:
- fallthrough, 强制执行下一个case子句(不再判断下一个子句的条件是否满足)
- default,当所有case分支都不符合时,执行default语句,并且default语句可以放在任意位置,并不影响swith的判断
for语句
for init;condition;post{}
for condition {} //while
for {} //while(1)
//访问map
for key,value:= range map{}
for key:=range map{}
//访问数组
for index, value:=range array{}
for index:=range array{}
for _, value:=range array{}
//访问切边
for index,value:=range slice{}
for index:=range slice{}
for _,value:=range slice{}
//访问通道
for value:=range channel{}
goto:
- goto语句只能在函数内跳转
- goto语句不能跳过内部变量声明语句,这些变量在goto语句的标签语句处又是可见的
goto L
v:=3
L:
- goto语句只能跳到同级作用域或上层作用域内,不能跳到内部作用域
if n%2 ==1 {
goto L1
}
for n > 0{
f()
n--
}
L1:
f()
n--
}
break:可以和标签一起使用,但是标签和break必须在同一个函数内
continue:可以和标签一起使用,但是标签和continue必须在同一个函数内
函数:
- 函数是一种类型,可以像其他类型变量一样使用,可以作为其他函数的参数或返回值,也可以直接调用执行
- 函数支持多值返回
- 支持闭包
- 函数支持可变参数
func funcName(param-list)(result-list){......}
//例如:
func add(a,b int) int{return a+b}
func add(a,b int) (sum int){
sum = a+b
return
}
- 不支持默认值参数
- 不支持函数重载
- 不支持函数嵌套,严格地说是不支持命名函数地嵌套定义,但支持嵌套匿名函数
func add(a,b int) (sum int){
anonymous := func(x