包 程序运行入口是 main 包
导入 使用 import 导入包
1 2 3 4 import  (    "fmt"      "math/rand"  ) 
可以一次导入多个包
导出 首字母大写是被导出的
1 2 3 4 5 6 7 8 package  mainimport  (    "fmt"      "math"  ) func  main ()     fmt.Println(math.Pi) } 
这里 PrintLn 和 Pi 首字母大写
函数 函数可以没有参数或者接受多个参数
1 2 3 4 5 6 7 8 9 10 11 package  mainimport  "fmt" func  add (x int ,y int )  int     return  x+y } func  main ()     fmt.Println(add(1 ,2 )) } 
这里会做设定变量类型设定,类型在变量名之后, 在大括号前做返回类型设定
函数可以返回多个值 ,如果连续多个函数参数都是同种类型,则类型判定可以写在最后
1 2 3 4 5 6 7 8 9 10 11 package  mainimport  "fmt" func  swap (x,y string ) (string ,string )     return  y,x } func  main ()     a,b :=swap("hello" ,"world" )     fmt.Println(a,b) } 
上面的 a,b:=xxxx类似解构复制
命名返回值 在函数大括号前的返回类型设定可以直接命名返回值,并且若返回值类型相同,类型也可以写在最后裸返回 ,返回
1 2 3 4 5 6 7 8 9 10 11 12 package  mainimport  "fmt" func  split (sum int ) (x,y int )     x=sum *4  /2      y=sum-x     return   } func  main ()     fmt.Println(split(20 )) } 
变量 使用 var 定义一个变量列表,类型在变量后面,var 可以写在包或者函数内零值
数值类型为 0 
布尔类型为 false 
字符串为 “” 空字符串 
 
1 2 3 4 5 6 7 8 9 10 11 12 package  mainimport  "fmt" var  js, c, java bool var  golang int func  main () 	var  i int  	fmt.Println(i, js, c, java, golang) } 
初始化变量 定义变量时候可以包含初始值
1 2 var  i,j int =1 ,2 var  c,py,java=true ,false ,"java8" 
如果初始化变量时候使用表达式,则可以省略定义类型,变量直接从初始值中获取类型 
短声明变量 函数中  :=简介赋值语句在明确类型的地方可以代替 var 的定义,其不能用在函数外
1 2 3 4 5 6 7 8 9 package  main import  "fmt" func  main ()     var  i,j=1 ,2      k:=3      c,py,java:=true ,false ,"java8"      fmt.Println(i,j,k,c,py,java) } 
打包声明 同打包引入一样,变量也可以打包声明
基本类型 
bool 
string 
int
int 
int8 (byte) 
int16  
int32 (rune) 
int64 
uint 
uint8 
uint16 
uint32 
uint64 
uintptr 
 
 
float32 
float63 
complex64 
complex128 
 
当无特别理由时候,定义整数类型时,首选 int
类型转换 直接使用‘基本类型方法’转换即可,例如
1 2 var  i int =42 var  f float64  =float64 (i)
go 需要显式转换:=
1 2 3 4 5 6 package  mainimport  "fmt" func  main ()      } 
类型推导 在下面这个例子中,使用了类型推导
i:=42 这里i为int类型,当为浮点数时,这个类型推导取决于赋值的常量精度。此时使用 fmt.Printf返回变量类型 
1 2 3 4 5 6 7 8 9 package  mainimport  "fmt" func  main () 	v := "232eqw4"  	fmt.Printf("type %T\n" , v) } 
上面这个 %T\n 会对返回的值做一次处理,不加上的话会返回
1 type %!(EXTRA string =232 eqw4)%
常量 常量使用 const 定义
for循环 go只有一种循环。for 循环
1 2 3 4 5 6 7 8 9 10 package  mainimport  "fmt" func  main ()     sum:=0      for  i:=0 ;i<10 ;i++{         sum+=1      }     fmt.Println(sum) } 
和js很像,只是没了 for 后面的条件语句的括号,并且
1 2 3 4 5 6 7 8 9 10 package  mainimport  "fmt" func  main ()     sum:=0      for  ;i<10 ;{         sum+=1      }     fmt.Println(sum) } 
省略分号 当省略分号时候,for循环即变成了 “while”循环
1 2 3 4 5 6 7 8 9 10 package  mainimport  "fmt" func  main ()     sum:=0      for  i<10 {         sum+=1      }     fmt.Println(sum) } 
if语句 同for语句,if语句也不需要把条件用括号括起来。并且在条件语句中执行的简单语句
switch语句 同if语句,其执行顺序是从上到下,当匹配成功时候停止执行,当switch没有设置条件时候
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package  mainimport  (    "fmt"      "time"  ) func  main ()     t :=time .Now ()      switch   {        case  t.Hour()<12 :             fmt.Println("good morning" )         case  t.Hour<17 :             fmt.Println("good afternoon" )         default  :             fmt.Println("good eveneing" )     } 
defer语句 defer语句会延迟函数的执行,直到上层函数返回,
1 2 3 4 5 6 7 8 9 10 package  mainimport  "fmt" func  main ()     defer  fmt.Println("world" )     fmt.Println("hello" ) } 
defer 栈 延时调用的函数会被压入到一个栈中,当函数调用时,会按照后进先出顺序
1 2 3 4 5 6 7 8 9 10 11 package  mainimport  "fmt" for  i:=0 ;i<10 ;i++{    defer  fmt.Println(i) } fmt.Println("start" ) 
指针 & 符号会生成一个作用其对象的指针, * 符号表示指针指向其底层的值
1 2 3 4 5 6 7 8 9 10 11 12 package  mainimport  "fmt" func  main ()     i:=13      p:=&i     fmt.Println(*p)        *p=233      fmt.Println(i)      fmt.Println(*p)  } 
结构体 struct 就是一个字段的集合,和js的对象相似
1 2 3 4 5 6 7 8 9 10 11 12 13 package  mainimport  "fmt" type  Vertex struct {    X int      Y int      Z int  } func  main ()     v:=Vertex{1 ,2 ,4 }     fmt.Println(v.X)  } 
通过 . 来读取和写入
结构体指针 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package  mainimport  "fmt" type  Vertex struct  {    X int      Y int  } func  main ()     v := Vertex{1 , 2 }     p := &v     p.X = 3      fmt.Println(v)     fmt.Println(*p) } package  mainimport  "fmt" type  Vertex struct  {    X int      Y int  } func  main ()     v := Vertex{1 , 2 }     p := v     p.X = 3      fmt.Println(v)     fmt.Println(p) } 
这里go和js第对象处理不同,js对象是引用传递的(默认就是传指针)
数组 1 2 3 4 5 6 7 8 9 10 package  mainimport  "fmt" var  a [10 ]int  func  main ()     var  b [2 ]string      b[0 ]="hello"      b[1 ]="world"      fmt.Println(b[0 ],b[1 ])   } 
数组slice 可以通过以下方式赋值
1 2 3 4 5 package  mainfunc  main ()     a:=[]int {1 ,2 ,3 ,4 ,5 } } 
这里的slice可以理解和数组的项,数组的slice也可以为一个slice,这样就可以是多维数组
对slice切片 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package  mainimport  "fmt" func  main () 	s := []int {2 , 3 , 5 , 7 , 11 , 13 } 	fmt.Println("s ==" , s) 	 	 	fmt.Println("s[1:4] ==" , s[1 :4 ])           	 	fmt.Println("s[:3] ==" , s[:3 ])           	 	fmt.Println("s[4:] ==" , s[4 :]) 	 } 
这里slice用法和js相同。
构造 slice slice可以由函数 make 创建。会分配一个全是零值的数组并返回一个slice指向这个数组
make函数接受三个参数,
这里cap是内建函数 容量
nil slice slice 的零值是 nil
一个nil 的slice的长度和容量是0
向slice末尾添加元素 使用内建函数 append,类似于js push
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package  mainimport  "fmt" func  main ()     var  a[]int ;     printSlice("a" ,a);      a=append (a,0 );     printSlice("a" ,a);     a=append (a,1 );     printSlice("a" ,a); } func  printSlice (s string ,x []int )     fmt.printf("%s len=%d cap=%d %v\n" ,     s,len (x),cap (x),x) } 
range for 循环的 range 格式可以对 slice 或者 map 进行迭代循环。
当使用 for 循环遍历一个slice时,没戏迭代range将返回两个值,一个是当前slice下标,一个是该
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package  mainimport  "fmt" var  pow = []int {1 , 2 , 3 , 4 }func  main () 	for  i, v := range  pow { 		fmt.Println(i, v) 	} } 
这里如果要忽略索引值可以把 i 换成 _ ,如果需要忽略value值,则把 v 和前面逗号删除即可。
map map 映射键到值
map在使用之前必须用make来创建;值为 nil 的 map 是空的,并且不能对其赋值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package  mainimport  "fmt" type  Vertex struct  {	x, y int  } var  m map [string ]Vertexfunc  main () 	m = make (map [string ]Vertex) 	m["index" ] = Vertex{ 		1 , 2 , 	} 	fmt.Println(m["index" ]) 	fmt.Println(m) } 
map有点像对象数组
map 语法 map语法和结构体语法类似,不过必须有键名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package  mainimport  "fmt" type  Vertex struct  {	x, y int  } var  m = map [string ]Vertex{	"index1" : Vertex{ 		1 , 2 , 	}, 	"index2" : Vertex{ 		3 , 4 , 	}, } func  main () 	fmt.Println(m) 	fmt.Println(m["index2" ]) } 
这里看到 map 和js中的对象是非常类似的。
操作map 在 map m中插入或者修改一个元素
获取元素
删除元素,使用内建函数delete
通过双赋值 检测某个键是否存在
如果key在m中,则ok为 true,否则,ok为false,并且elem值是map这个元素类型的零值。
函数的闭包 Go函数可以是一个闭包。闭包是一个函数值,他引用了函数体之外的变量。这个函数可以对这个引用的变量进行访问赋值。