GO Language 快速入门。冲冲冲!本文适合有其他编程语言基础的读者阅读。
全局变量和 const 变量可以没有初值。
语句结尾加分号是多余的。加了分号,在保存时会被自动移除。
使用 := 给变量赋初值时,可以不用 var 和类型,类型是自动推断的,这看上去像是动态语言,实则是静态的。
var a int = 3 // [a] is an [int] typed variable with value [3]var b = 3 // 自动类型推断a := "Hello" // 省略var的自动类型推断条件控制语句可以没有括号。没有 while 和 do。
for 循环的写法:
xxxxxxxxxx// 普通for循环for i:=1; i<10; i++ { println(i)}// 把它当while用for a<b { a++}函数写法如下,注意在没有返回值时,不用写返回值:
xxxxxxxxxx// 普通函数func MyFunction(a int, b int) int { return a + b}// 从java那里拿来的不定长参数列表func MyFunction(arr ...int) { fmt.Println(arr)}数组相关:
xxxxxxxxxxvar arr [5] int // [arr] is an size [5] array with [int] type//[arr2] is an size [5] array with type[float32] inited with {1,2,3}var arr2 = [5] float32 {1,2,3}var arr3 = [] uint64 {1,2,3,4,5,6}如何快速的遍历一个数组:
xxxxxxxxxxfor i,x := range arr { fmt.Printf('Pos=%d\tValue=%d\n', i, x)}指针,和 C 语言完全一样
xxxxxxxxxxvar a int = 5var ptr *int = &avar pptr **int = &ptr //ptr to a ptrfmt.Printf("Address of a = %p\n", ptr)fmt.Printf("Address of ptr = %p\n", pptr)fmt.Printf("Value of a = %d\n", *ptr) //value of which ptr pointedfmt.Printf("Value of a = %d\n", **pptr) //value of value of a ptr指针数组:
xxxxxxxxxxvar arr = [10]int{1,2,3,4,5}ptrarr := [10]*int{}for i,x := range arr { ptrarr[i] = &x}for i:=0; i<10; i++ { fmt.Printf("ptrarr[%d]=%p", i, ptrarr[i])}结构体
xtype Books struct { name string price float32}var book1 Booksvar book2 Booksbook1.name = "Asd"book1.price = 64book2.name = "GOGOGO"book2.price = 128接口,定义要实现的方法,用于把方法连接到 struct 上,这样 struct 只管属性成员就可以了。相当于把 class 拆成了成员属性 + 方法。
注意引用传递和值传递的区别。
xxxxxxxxxxtype Employee interface { AddSalary(int) GetSalary()}type Manager struct { wage int name string}func (man *Manager) AddSalary(sal int) { man.wage += sal}func (man *Manager) GetSalary() { println(man.wage)}func main { var man1 *Manager = new(Manager) man1.wage = 10 man1.AddSalary(10) man1.GetSalary()}哈希表的创建、删除key、pythonic遍历
xxxxxxxxxxvar hashmap map[string]int = make(map[string]int)hashmap2 := map[string]int{"Tuesday":2, "Friday":5}hashmap["jack"] = 1hashmap["sam"] = 2hashmap["iris"] = 4delete(hashmap, "jack")for key, value := range hashmap { println(key, "\t", value)}切片是一种动态数组
xxxxxxxxxxvar slice = make([]int, 0, 1) //make(type, len, cap)//var slice []int 也可,此时初始化为nilslice = append(slice, 1, 2, 3, 4, 5)for i := 0; i < len(slice); i++ { fmt.Println(slice[i])}fmt.Println(cap(slice))fmt.Println(slice)fmt.Println(slice[0:5])var slice2 []intcopy(slice2, slice) //from slice to slice2GoRoutine,是 go 语言线程,但随着主线程结束而结束,因此称协程
xxxxxxxxxximport "runtime"func say(str string) { println(str) runtime.GoSched() //相当于java yield,让出cpu时间片}func main() { go say("Hi") go say("Hello") var wait string fmt.Scanln(&wait) //主线程不能在 go 协程执行完毕前结束}Channel,用于从 GoRoutine 取得数据,可看成队列。不带缓冲区时为同步操作,否则可认为是异步操作。
xxxxxxxxxxfunc channelTest() { ch := make(chan int) //FIFO队列,指明元素类型,第二个参数可省略,指缓冲区的大小 go fib(15, ch) var k int //直接取出方式 for i := 0; i < 5; i++ { k = <-ch println(k) } //遍历channel的取出方式 for value := range ch { println(value) }}func fib(n int, ch chan int) chan int { a := 1 b := 1 if n <= 2 { ch <- a ch <- b return ch } else { for i := 3; i <= n; i++ { if i%2 == 1 { a = a + b ch <- a } else { b = b + a ch <- b } } } close(ch) return ch}错误/异常处理,方法是实现 Error 方法。
xxxxxxxxxximport "os"// 定义异常结构体type DivisionByZeroException struct { divider float32 dividee float32}// 实现Error方法func (exception DivisionByZeroException) Error() string { return fmt.Sprintf("Divider=%f, Dividee=%f", exception.divider, exception.dividee)}//除法函数func divide(divider float32, dividee float32) float32 { if dividee == 0 { //被0除时打印异常 errorObj := new(DivisionByZeroException) errorObj.divider = divider errorObj.dividee = dividee msg := errorObj.Error() fmt.Println(msg) //强制退出 os.Exit(1) return -1 } else { return divider / dividee }}func main() { divide(1, 0)}