go语言语法记录

go

  • 基本语法
    • 变量

      • 变量类型
        变量类型有哪些?

        var value string = "haha

      • 包内变量

        不可以使用:=符号来定义变量

      • 函数内变量
        可以使用 :=定义,然后只在函数内有效
        定义即需要使用

      • 自动类型推断

        var value = "haha
        value := "haha

      • 强制类型转换

        c = int(math.Sqrt(float64(a*a+ b*b)))
        
      • 常量的定义

        const filename = 'abc.txt'

        const 数值可以作为各种类型使用,在你没有指定类型的情况下,它可以直接将值拷贝给其他类型

        const a,b = 3,4
        var c int = int(Math.Sqrt(a*a+b*b))
        
      • 枚举类型

        • 普通枚举

          	const (
          		a = 1
           		b = 2
          		c = 3
          		d = 4
          	)
          
        • 自增值枚举类型

          const (
          		a = iota	
           		b 
          		c 
          		d 
          	)
          
    • 条件语句

      • if没有括号
      • if 条件里可以赋值,且赋值的变量作用域只在if里可以用
      func bounded (v int ) int {
      	if v>100 {
      		return 100
      	}else if v < 0 {
      		return 0
      	}else {
      		return v
      	}
      }
      
      • switch 不需要break语句,除非使用fallthrough来主动添加break

      • switch 后面可以没有表达式

        func grade(score int) string {
        	value := ""
        	switch {
        	case score < 0 || score > 100:
        		value = "error"
        	case score < 60:
        		value = "不及格"
        	case score < 80:
        		value = "及格"
        	case score < 100:
        		value = "良好"
        	case score == 100:
        		value = "优秀"
        	}
        	return value
        }
        
    • 循环

      • for
        • for 的条件里不需要括号
        • for的条件里可以省略初始条件,结束条件,递增表达式(省略递增条件后就是一个死循环了)
      • 没有while
    • 函数

    • 指针

      package main
      
      import "fmt"
      
      func voidCopy (a int) {
      	a++
      }
      func voidRef(a *int) {
      	*a++
      }
      
      func main() {
      	a := 3
      	voidCopy(a) // 这里只是拷贝了一份值过来进行运算
      	fmt.Println(a)
      	voidRef(&a) // 这里是直接取变量地址传入后取值进行自增
      	fmt.Println(a)
      }
      

      看到指针就应该思考到值传递还是引用传递?go语言函数只有值传递一种方式,所有参数都会被拷贝一份,思考当传递的参数是一个数值的时候,可以考虑使用指针获取地址进行传递直接修改原数据,而如果传递的参数是对象等引用类型的话,那么传递过来的本身就是引用地址!

    • 数组

      var arr1 [5]int
      arr2 := [3]int {3,4,5}
      arr3 := [...]int {3,4,5,6,7}
      var grid [4][5]int
      
      // range 下列写法可以获得下标和值
      for i, v := range arr3 {
      	fmt.Println(i)
      	fmt.Println(v)
      }
      
      // 定义必须得用,所以可以使用下划线进行省略变量
      for _, v := range arr3 {
      	fmt.Println(v)
      }
      

      数组是值类型(使用的时候是拷贝)调用它的时候是值拷贝,一般不使用数组而是使用切片

      func printArray(arr [5]int) {
      	for i,v :=range arr {
      		fmt.Println(i,v)
      	}
      }
      // arr2 和 arr3、arr1不同,它不是[5] int 类型的
      printArray(arr3)
      printArray(arr1)
      //printArray(arr2)
      
    • 切片

      slice

      arr := [...]int {0,1,2,3,4,5,6,7,8,9}
      fmt.Println("arr: ", arr )
      fmt.Println("arr[2:6]: ",arr[2:6])
      fmt.Println("arr[:6]: ",arr[:6])
      fmt.Println("arr[2:]: ",arr[2:])
      fmt.Println("arr[:]: ",arr[:])
      // output
      arr:  [0 1 2 3 4 5 6 7 8 9]
      arr[2:6]:  [2 3 4 5]
      arr[:6]:  [0 1 2 3 4 5]
      arr[2:]:  [2 3 4 5 6 7 8 9]
      arr[:]:  [0 1 2 3 4 5 6 7 8 9]
      

      slice本身没有数据,是对底层array的一个view

      func main() {
      	arr := [...]int {0,1,2,3,4,5,6,7,8,9}
      	s := arr[:]
      
      	s[0] = 20
      	s[3] = 200
      	fmt.Println(arr)
      }
      //  [20 1 2 200 4 5 6 7 8 9]
      

      Reslice

      arr := [...]int {0,1,2,3,4,5,6,7,8,9}
      fmt.Println(arr)
      s := arr[:5]
      fmt.Println(s)
      s = s[:2]
      fmt.Println(s)
      // output
      // [0 1 2 3 4 5 6 7 8 9]
      // [0 1 2 3 4]
      // [0 1]
      

      超出切片的下标会如何显示?

      arr := [...]int {0,1,2,3,4,5,6,7,8,9}
      fmt.Println(arr)
      s := arr[2:5]
      fmt.Println(s)
      s1 := s[3:5]
      fmt.Println(s1) 
      // output 
      /* 
      [0 1 2 3 4 5 6 7 8 9]
      [2 3 4]
      [5 6]
      */
      

      sliceptr,len,cap分别第一个,长度,向后的全部元素

      slice 可以向后扩展,不可以向前扩展,s[i]不可以超过len(s),向后扩展不可以超过底层数组cap(s)

      • 切片的操作

        1. 如何添加数字?

          s = append(s1,val)

          由于值传递的原因,必须接受append的返回值

          添加元素时如果超越cap,系统会重新分配更大的底层数组

    • 容器

  • 面向接口
    • 结构体
    • dock typing
    • 组合的思想

posted on 2019-08-23 10:22  2481  阅读(103)  评论(0编辑  收藏  举报

导航