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)
}
数组相关:
xxxxxxxxxx
var 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}
如何快速的遍历一个数组:
xxxxxxxxxx
for i,x := range arr {
fmt.Printf('Pos=%d\tValue=%d\n', i, x)
}
指针,和 C 语言完全一样
xxxxxxxxxx
var a int = 5
var ptr *int = &a
var pptr **int = &ptr //ptr to a ptr
fmt.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 pointed
fmt.Printf("Value of a = %d\n", **pptr) //value of value of a ptr
指针数组:
xxxxxxxxxx
var 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 Books
var book2 Books
book1.name = "Asd"
book1.price = 64
book2.name = "GOGOGO"
book2.price = 128
接口,定义要实现的方法,用于把方法连接到 struct 上,这样 struct 只管属性成员就可以了。相当于把 class 拆成了成员属性 + 方法。
注意引用传递和值传递的区别。
xxxxxxxxxx
type 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遍历
xxxxxxxxxx
var hashmap map[string]int = make(map[string]int)
hashmap2 := map[string]int{"Tuesday":2, "Friday":5}
hashmap["jack"] = 1
hashmap["sam"] = 2
hashmap["iris"] = 4
delete(hashmap, "jack")
for key, value := range hashmap {
println(key, "\t", value)
}
切片是一种动态数组
xxxxxxxxxx
var slice = make([]int, 0, 1) //make(type, len, cap)
//var slice []int 也可,此时初始化为nil
slice = 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 []int
copy(slice2, slice) //from slice to slice2
GoRoutine,是 go 语言线程,但随着主线程结束而结束,因此称协程
xxxxxxxxxx
import "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 取得数据,可看成队列。不带缓冲区时为同步操作,否则可认为是异步操作。
xxxxxxxxxx
func 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 方法。
xxxxxxxxxx
import "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)
}