go语言特性:
◆ 自动垃圾回收
具备系统自动释放资源
◆更丰富的内置类型
map类型、slice类型(类似vector)
◆函数多返回值
跟lua/erlang一样,支持函数多返回值,优化输入输出参数、结构体参数等传递
◆错误处理
defer/recover/panic,
defer用于资源的释放,go语言不提供构造和析构,
recover截取错误处理流程,一般在使用defer的关键字函数中使用;若在无异常的goroutine中使用recover,会导致此goroutine所在的进程打印错误信息后,直接退出
◆匿名函数
a := fun() / a();
◆类型、接口
类型struct,类似C的结构体,但不支持继承和重载;
接口:非入侵式接口、interface{}作为函数参数,可传递任何类型
◆并发
吸取erlang语言的面向消息编程机制,所有的数据交互都用goroutine的消息传递
◆反射
模仿java语言的反射特性,但不像java内置类型工厂
◆语言的交互性
go语言通过Cgo库,可混合编写C语言代码
golang并发:
golang为实现高并发性,引入了goroutine,通过channel模式用CSP(通信顺序进程,Communicating Sequential Process)模型实现goroutine之间的数据交互;
golang的并发系统,由N个并行运行的CSP组成,每个CSP之间都是资源独立的,通过go提供的通信原语进行消息传递,通过类似管道的channel模式,来实现CSP,从而达到跨越goroutine的通信。
此外,一个进程中的所有协程goroutine都在同一个内存空间中,所以不同的goroutine要去访问共享的内存变量时,需要访问读写锁,由go语言的sync库提供读写锁功能。
作用域:
小字母开头命名,只包内可见
大字母开头命名,包内外可见
适用于变量、类型、函数
go内置数据类型:
◆ 布尔bool
bool类型值只有true、false,不能复制为数值1、0等
◆ 整型:
int8/byte(uint8)/int16/uint16/int32/uint32/int64/uint64/int/uint/uintptr
int/uint:平台相关,32位4字节,64位8字节
uintptr :平台相关指针
int、int32 :go语言认为是两种类型,go语言不支持隐式类型转换,而且不支持不同类型的比较,比较必须是严格的“相同”类型,类型转换必须显示强转;若比较int32和int16类型的,编译器会报错;给变量赋值时,a := 12、b := 12.0会对变量类型进行自动推导,a为整型,b为浮点型。
◆ 浮点型float32/64
v1 := 12.0,系统进行自动推导时,v1为float64类型的
◆ 复数complex64/128
数学上的复数:3.2 + 12i,具备实部与虚部的概念
◆ 字符串string
go语言的string类型是内置的
◆ 字符rune
byte(uint8) : 代表utf-8的字符类型,占一个字节
rune : 代表Unicode字符,go标准库的unicode包提供相关操作,unicode/utf-8的包提供unicode/utf-8之间的转换
◆ 错误error
◆ 指针pointer
◆ 数组array
[32]byte // 长度为32的数组,每个元素为一个字节
[2*N] struct{ x, yint32} //复杂类型数组
[1000]*float64//指针数组
[3][5]int // 二维数组
[2][2][2]float64//等同于[2]([2]([2]float64))
注意:数组是值类型,故作为函数参数传递时,是值传递,传递的是一个数组的副本,即作为函数参数传递的数组是无法被修改的
◆ 切片slice
类似vector,具备cap容量的概念
slice的创建:创建、基于数组创建、基于切片创建
myArr := {1,2,3,4,5}
mySlice := myArr[:5] //myArr[first : last],用myArr的前5个元素创建Slice
mySlice := make([]int, 5) //创建5个为0的Slice
mySlice := make([]int, 5, 10) //len(mySlice)是5,cap(mySlice)是10
mySlice := []int{1,2,3,4,5}
oldSlice := []int{1,2,3,4,5}
newSlice := oldSlice[:6] ==>若oldSlice的元素个数不足,用0补全newSlice
slice的append:切片内容的附加
mySlice := []int{1,2,3,4,5}
mySlice = append(mySlice, 1,2,3) //第二个参数以右边的是不定参数类型
mySlice2 := []int{8,9,10}
mySlice = append(mySlice, mySlice2 ...)
//不定参数,省略号;第二个参数mySlice2后面加了三个点,即一个省略号,如果没有这个省
略号的话,会有编译错误,因为按append()的语义,从第二个参数起的所有参数都是待附加的
元素。因为mySlice中的元素类型为int,所以直接传递mySlice2是行不通的。加上省略号相
当于把mySlice2包含的所有元素打散后传入。
上述调用等同于:
mySlice = append(mySlice, 8, 9, 10)
数组切片会自动处理存储空间不足的问题。如果追加的内容长度超过当前已分配的存储空间
(即cap()调用返回的信息),数组切片会自动分配一块足够大的内存。
slice内容复制:copy(dstSlice, resSlice)
slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{5, 4, 3}
copy(slice2, slice1) //只会复制slice1的前3个元素到slice2中
copy(slice1, slice2) //只会复制slice2的3个元素到slice1的前3个位置
◆ 字典map
==========================================================================
package main
import "fmt"
// PersonInfo是一个包含个人详细信息的类型
type PersonInfostruct{
ID string
Name string
Address string
}
func main(){
var personDB map[string] PersonInfo
personDB = make(map[string] PersonInfo)
personDB["12345"] = PersonInfo{"12345", "Tom", "Room 202, ..."}
personDB["1"] = PersonInfo{"1", "Jason", "Room 101, ..." }
person, ok := personDB["1234"]
if ok{
fmt.Println("Found person", person.Name, "with ID 1234.");
} else {
fmt.Println("Did not find person whit ID 1234.")
}
}
==========================================================================
var myMap map[string] PersonInfo
myMap = make(map[string] PersonInfo)
myMap := make(map[string] PersonInfo)
myMap := make(map[string] PersonInfo, 100) //预留100个PersonInfo空间
delete(myMap, "1234")
delete(myMap, nil) ==>编译器报错
◆ 通道 chan
◆ 结构体struct
◆ 接口interface
go变量与常量
◆ 变量 :golang用变量首字母大小写来控制访问权限,大写首字母开头可被包外访问,小写则只能包内访问
var v1 int = 10
var v2 = 10
v3 := 10
var i int var i int
i := 2 ==>编译器报错 i = 2 ==>正确
i, j = j, i //多重赋值 ==> C++: t = i; i = j; j = t;
_, _, nickName := GetName() //匿名变量 "_"
◆ 常量
字面常量:无类型的,只要在值域范围内,就可以作为该类型常量
-12 //整型常量,-12可以赋值给int、uint、int32/64、float32/64、complex64/128
3.14 //浮点型常量
3.2+12i //复数型常量
true //布尔型常量
"str" //字符串常量
常量定义:const关键字
const Pi float64 = 3.14159265358979
const (
size int64 = 1024
eof = -1
)
预定义常量:true、false、iota
iota比较特殊,可以被认为是一个可被编译器修改的常量,在每一个const关键字出现时被
重置为0,然后在下一个const出现之前,每出现一次iota,其所代表的数字会自动增1。
从以下的例子可以基本理解iota的用法:
const ( // iota被重设为0
c0 = iota // c0 == 0
c1 = iota // c1 == 1
c2 = iota // c2 == 2
)
const (
a = 1 << iota // a == 1 (iota在每个const开头被重设为0)
b = 1 << iota // b == 2
c = 1 << iota // c == 4
)
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
numberOfDays // 这个常量没有导出
)
go流程控制
◆ if
===================================================================================
if a > 0 {
}
if i :=0; i < 0{
}
func exfunc(x int) int{
if x == 0 {
return 5
} else {
return x ==>编译器报错,必须有路径进行return,这里不能是最终的return
}
//return 0
}
===================================================================================
◆ switch : case 不支持break
◆ for : 不支持逗号多重赋值,支持continue、break控制循环
===================================================================================
for j := 0; j < 5; j++{
for i := 0; i < 10; i++{
if i > 5{
break JLoop
}
}
}
JLoop: ...
===================================================================================
===================================================================================
for i := 0; i < len(arr); i++{
...
}
for i, v := range arr{
...
}
===================================================================================
===================================================================================
for i := 0; i < len(mySlice); i++{
...
}
for i, v := range myslice{
...
}
===================================================================================
===================================================================================
func myfunc(args ...int){//...type格式类型(syntactic sugar),只作为函参存在,且是最后一个参数
for _, arg := range args{
fmt.Println(arg)
}
}==>myfunc(2,3,4);myfunc(4,5,6,4,65)
===================================================================================
◆ goto
func myfunc(){
i := 0
HERE:
fmt.Println(i)
i++
if i < 10 {
goto HERE
}
}
go函数
◆ 函数定义
◆ 函数调用
◆ 不定参数
===================================================================================
func myfunc(args ...int){ //接受不定数量的参数,全部为int
for _, arg := range args{
fmt.Println(arg)
}
}==>myfunc(2,3,4);myfunc(4,5,6,4,65)
//...type格式类型,本质是一个slice, []type
func myfunc(args ...int){
myfunc3(args ...)
myfunc3(args[1:] ...) int
}
fmt.Printf()的函数原型
func Printf(format string, args ... interface{}){ //interface{}传递任意类型数据
...
}
◆ 多返回值
◆ 匿名和闭包
go错误处理
◆ defer
◆ recover
◆ panic
◆ error
6g, 6l ==> 6go, 6link 64位,编译,link
8g, 8l ==> 8go, 8link 32位,编译,link
gccgo
>7.1 version GDB ==> gdb calc DWARFv3
有疑问加站长微信联系(非本文作者)