golang note

xianddd · · 713 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go的基本设计理念是:编译效率,运行效率和开发效率要三者兼顾。

【特性】
1、并行机制\协程-多核应用、网络应用
2、结构化类型-弹性模块化程序
3、机器码编译、GC、反射
4、静态类型语言-运行效率
编译器: GCCgo\6g\8g

【环境变量】
a.添加系统变量GOROOT = C:\Go
b.修改环境变量PATH = %GOROOT%\bin
c.添加系统变量GOPATH:用来设置包加载路径的重要变量,可设置多个路径,设置项目路径可下载各种依赖关系。

【关键词】
var const func type struct map interface
select defer chan fallthrough range 

【数据类型】
布尔类型
数字类型
字符串类型
派生类型:
(a) 指针类型(Pointer)
(b) 数组类型
(c) 结构化类型 (struct)
(d) 联合体类型 (union)
(e) 函数类型
(f) 切片类型
(g) 接口类型(interface)
(h) Map 类型
(i) Channel 类型
& 返回地址变量
* 返回指针变量

有符号整数 
int (位数随系统,默认) 
int8 (-128~127) 
int16 (-32768~32767) 
int32 (-2147483648~2147483647)(类似rune) 
int64 
无符号整数 
uint (位数随系统) 
uint8 (0~255)(类似byte)
uint16 (0~65535)
uint32 (0~4294967295)
uint64 
uintptr 用于存放指针
浮点 float32 float64 (默认)
复数 complex64 complex128


【变量定义】并行赋值
var vname1, vname2 type //声明后若不赋值使用默认值
var vname1, vname2 = val1, val2 //根据值自行判定变量类型
vname1, vname2 := val1, val2 //:=格式只能用在函数体内,注意 :=左侧变量不能是已经声明过的,否则编译错误
var ( 
    vname1 v_type1
    vname2 v_type2
)
交换两个变量的值,可以简单地使用 a, b = b, a
val1, val2 = ReturnVals() //一个函数多个返回值

var a int=1
var b, c, d = -1, 2.0, true
e:="foo"
const MAX int = 100
var ptr *int=&a //指针初始化为nil,值为0,ptr==nil
var ptr2 **int=&ptr//指针的指针
fmt.Println("Hello World!")
fmt.Println("a=",a,", b=",b)
fmt.Println("a=%d, b=%d",a,b)
fmt.Println(a,b,c,d,e,ptr,ptr2) //int int float64 bool string *int **int
fmt.Printf("val: %d %f %s %d %d %x \n", a,c,e,*ptr,ptr) //格式输出

常量可用作枚举
const ( 
    Female = 1
    Male = 2
)
常量可用len(), cap(), unsafe.Sizeof() 计算表达式,函数必须是内置函数
import "unsafe"
const (
    a = "abc"
    b = len(a)
    c = unsafe.Sizeof(a)
)
iota 特殊常量,每出现一次iota自动加1,在每次const关键字出现时被重置为0
const (
    a = iota   //0
    b              //1
    c = "ha"   //独立值,iota += 1
    d              //"ha"   iota += 1
    e = iota   //4,恢复计数
    f                  //5
)
const (
    i=1<<iota  //i=1<<0
    j=3<<iota  //j=3<<1
    k                //k=3<<2
    l                //l=3<<3
)

【switch有两种类型】
switch var1 可以是任何类型
switch 语句不需加break
表达式Switch
   var grade string = "B"
   var marks int = 90
   switch marks { //对值分支
      case 90: grade = "A"
      case 80: grade = "B"
      case 60,70 : grade = "C"
      default: grade = "D"  
   }
   switch { //对表达式分支
      case grade == "A" :
         fmt.Printf("Excellent!\n" )     
      case grade == "B", grade == "C" :
         fmt.Printf("Well done\n" )      
      case grade == "D" :
         fmt.Printf("You passed\n" )      
      case grade == "F":
         fmt.Printf("Better try again\n" )
      default:
         fmt.Printf("Invalid grade\n" );
   }
类型Switch
switch x.(type){
    case type:
       statement(s);      
    default:
       statement(s);
}
   var x interface{} //必须有接口的变量表达式{}输入
   switch i := x.(type) {
      case nil:      
         fmt.Printf("%T",i)                
      case int:      
         fmt.Printf("x is int")                       
      case float64:
         fmt.Printf("x is float64")           
      case func(int) float64:
         fmt.Printf("x is func(int)")                      
      case bool, string:
         fmt.Printf("x is bool or string")       
      default:
         fmt.Printf("don't know the type")     
   }

select是一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收。
如果有多个case都可以运行,Select会随机执行一个,其他不会执行。
如果没有case可运行(没有default),它将阻塞,直到有case可运行。
func main() {
   var c1, c2, c3 chan int
   var i1, i2 int
   select {
      case i1 = <-c1:
          fmt.Printf("received ", i1, " from c1n")
       case c2 <- i2:
          fmt.Printf("sent ", i2, " to c2n")
       case i3, ok := (<-c3):  // same as: i3, ok := <-c3
          if ok {
             fmt.Printf("received ", i3, " from c3n")
          } else {
             fmt.Printf("c3 is closedn")
          }
       default:
          fmt.Printf("no communicationn")
    }    
 }
 
【for循环有三种】
for [condition |  ( init; condition; increment ) | Range] { }
for a := 0; a < 10; a++ { }
for a < b { } //while
for { } //for(;;)  for true {}
for 循环的 range 可以对 数组、切片、字符串、集合等进行迭代循环
for index, value := range numbers1 { } //数组
for _, value := range slice1 { } //切片不需索引使用_占位
for key, value := range map1 { }
for i, c := range "go" { } //枚举Unicode字符串

//goto跳转-避免使用
var a int = 10
LOOP: for a < 20 {
  if a == 15 {
     a = a + 1
     goto LOOP
  }
  fmt.Printf("%d\n", a)
  a++     
}


【数组】-定长
var numbers1 [5] int //[0 0 0 0 0]
var numbers2 = [5]int{1, 2, 3, 4} //[1 2 3 4 0]
var numbers3 = []int{1, 2, 3, 4} //[1 2 3 4]
var numbers4 [5][5]  int
fmt.Println(numbers1)

var ptr [5] *int //指针数组,不是指向数组的指针
for  i := 0; i < 5; i++ {
  ptr[i] = &numbers2[i]
  fmt.Println(*ptr[i])
}

for i:= range numbers2 {
  fmt.Println(i,"=",numbers2[i])
}

//数组参数必须定义一致才能传递
void myFunction(param [5]int) //param := [5]int{1, 2, 3, 4}
void myFunction(param []int) //param := []int{1, 2, 3, 4}
   
【切片】-抽象数组-不定长
var numbers1 [] int //未初始化前默认为 nil,长度容量为零
printSlice(numbers1) //len=0 cap=0 slice=[]
numbers1 = []int{0,1,2,3,4,5,6,7,8}
printSlice(numbers1) //len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]
printSlice(numbers1[:]) //同上
printSlice(numbers1[1:5]) //len=4 cap=8 slice=[1 2 3 4]
printSlice(numbers1[5:]) //len=4 cap=4 slice=[5 6 7 8]
printSlice(numbers1[:5]) //len=5 cap=9 slice=[0 1 2 3 4]

numbers1 = make([]int,3,5) //创建切片
printSlice(numbers1) //len=3 cap=5 slice=[0 0 0]
//想增加切片的容量,必须创建一个新的更大的切片并把原分片的内容都拷贝过来
numbers2 := make([]int, len(numbers1), (cap(numbers1))*2)
copy(numbers2,numbers1) //numbers1复制到numbers2
printSlice(numbers2) //len=3 cap=10 slice=[0 0 0]

numbers1 = append(numbers1, 9,10)
printSlice(numbers1) //len=11 cap=18 slice=[0 1 2 3 4 5 6 7 8 9 10]

func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}
【管道】

【集合】
var map1 map[string]string = make(map[string]string) //make定义
map1 = map[string] string {"a":"A","b":"B"} //定义
map1["c"]="C"
delete(map1,"b");
for k,v := range map1 {
   fmt.Println(k,"=",v)
}
v, ok := map1["a"]
if(ok){
  fmt.Println("a present", v)  
}

【结构体】
type Books struct {
   title string
   author string
   book_id int
}
var book1 Books
book1.title = "Go语言"
book2 := Books{"Go语言第2版", "xx","B01"}
book1=book2 //副本
var book3 *Books //结构体指针
book3=&book2 //引用
book3.title = "Go语言第3版" //访问成员跟变量一样


【函数】
func function_name( [parameter list] ) [return_types] {
   /* 函数实现 */
}

func getSum(num1, num2 int) int {
  return num1+num2
}
getSum := func(num1, num2 int) int { //定义函数变量,函数作值
  return num1+num2
}
func swap(x, y int)(int, int){ //函数返回多个值
    return y,x
}
func swap1(x, y int){
    temp := x
    x = y
    y = temp
}
func swap2(x, y *int){ //指针参数
    temp := *x
    *x = *y
    *y = temp
}
func main() {
    a, b :=1,2
    fmt.Println(getSum(1, 2))
    swap(a,b)
    fmt.Println(a, b)    //1,2
    swap2(&a,&b)
    fmt.Println(a, b)    //2,1
}

【函数作闭包-匿名函数】
匿名函数的优越性在于可以直接使用函数内的变量,不必申明
//函数getSequence() 返回另外一个函数,该函数的目的是在闭包中递增 i 变量
func getSequence() func() int {
   i:=0
   return func() int {
      i++
      return i  
   }
}
func main(){
   nextNumber := getSequence()  
   fmt.Println(nextNumber(),nextNumber())//1,2
   nextNumber1 := getSequence() //重新返回函数i从0开始 
   fmt.Println(nextNumber1(),nextNumber1())//1,2
}

【函数方法】
func (v_name v_type) function_name() [return_type] {}

【接口】
/* 定义接口 */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
}
/* 定义结构体 */
type struct_name struct {
   /* variables */
}
/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
   /* 方法实现 */
}

// 定义结构体(子类),实现接口方法
type Phone interface { //定义接口
    call()
}
type NokiaPhone struct { //定义结构体(子类)
}
func (nokiaPhone NokiaPhone) call() { //实现接口方法
    fmt.Println("I am Nokia, I can call you!")
}
type IPhone struct { //定义结构体(子类)
}
func (iPhone IPhone) call() { //实现接口方法
    fmt.Println("I am iPhone, I can call you!")
}
func main() {
    var phone Phone
    phone = new(NokiaPhone)
    phone.call()
    phone = new(IPhone)
    phone.call()
}

type Shape interface {
   area() float64
}
type Rectangle struct {
   x,y float64
}
//属于Rectangle对象的方法、实现接口Shape.area()
func(rectangle Rectangle) area() float64 { 
   return rectangle.x * rectangle.y
}
//给Shape定义方法
func getArea(shape Shape) float64 { 
   return shape.area()
}
func printRectangle(rectangle1 Rectangle,rectangle2 *Rectangle){
   fmt.Println(rectangle1,rectangle2)
   rectangle1.x=2
   rectangle2.x=2//改变了参数值
}
func main(){
   //传参数值变化
   var rectangle1,rectangle2 Rectangle
   rectangle1.x=1
   rectangle2.x=1
   printRectangle(rectangle1,&rectangle2) 
   fmt.Println(rectangle1,rectangle2)
   
   //接口方法调用
   rectangle3 := Rectangle{x:1,y:2} //指定参数赋值不受顺序、数量限制
   fmt.Println(rectangle3,rectangle3.area(),getArea(rectangle3))
}


有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:xianddd

查看原文:golang note

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

713 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传