1.Go 语言原理与实践 | 青训营

57 阅读3分钟

1.走进Go语言基础语法

1.1 什么是go语言

  1. 高性能,高并发
  2. 语法简单,学习曲线平缓
  3. 丰富的标准库
  4. 完善的工具链
  5. 静态链接
  6. 快速编译
  7. 跨平台
  8. 垃圾回收机制

2.1 基础语法

  1. hello world
package main

import (
	"fmt"
)

func main() {
	fmt.Println("hello world")
}
  1. 定义变量/常量 var/const
package main

import (
   "fmt"
   "math"
)

func main() {
   var a = "initial"
   var b, c int = 1, 2
   var d = true
   var e float64
   f := float32(e)
   g := a + "foo"
   fmt.Println(a, b, c, d, e, f, g)
   const s string = "constant"
   const h = 50000000
   const i = 2e20 / h
   fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
}
  1. 循环 for
package main

import (
   "fmt"
)

func main() {
   i := 1
   for {
      fmt.Println("loop")
      break
   }
   for j := 0; j < 10; j++ {
      fmt.Println(j)
   }
   for i <= 3 {
      i = i + 1
      fmt.Println(i)
   }
}
  1. if
package main

import (
   "fmt"
)

func main() {
   if num := 10; num < 15 {
      fmt.Println("num = 10 & num < 15")
   } else if num > 15 {
      fmt.Println("num > 15")
   }
}
  1. switch
package main

import (
   "fmt"
   "time"
)

func main() {
   a := 2
   switch a {
   case 1:
      fmt.Println("one")
   case 2:
      fmt.Println("two")
   case 3:
      fmt.Println("three")
   case 4, 5:
      fmt.Println("four or five")
   default:
      fmt.Println("other")
   }
   t := time.Now()
   switch {
   case t.Hour() < 12:
      fmt.Println("It's before noon")
   default:
      fmt.Println("It's before noon")
   }
}
  1. 数组
package main

import (
   "fmt"
)

func main() {
   var a [5]int
   a[4] = 100
   b := [5]int{1, 2, 3, 4, 5}
   c := [5]string{"qwqw", "fsfdf", "fsfdf", "earer", "sefesf"}
   for i := 0; i < 5; i++ {
      fmt.Println(b[i])
   }
   fmt.Println(a, len(a))
   fmt.Println(c, len(c))
   var twoD [2][3]int
   for i := 0; i < 2; i++ {
      for j := 0; j < 3; j++ {
         twoD[i][j] = i + j
      }
   }
   fmt.Println("td:", twoD)
}
  1. slice 切片:
  • 切片slice的底层数据是数组,slice是对数组的封装,它描述一个数组的片段。两者都可以通过下标来访问单个元素。 数组是定长的,长度定义好之后,不能再更改。而切片则非常灵活,它可以动态地扩容。切片的类型和长度无关。 数组就是一片连续的内存,slice 实际上是一个结构体,包含三个字段:长度、容量、底层数组。
  • 切片是围绕动态数组概念构建的。但是切片本身并不是动态数组,而是对底层数组的抽象。
  • 按需自动改变大小。
  • 与数组相比,切片的长度可以在运行时修改。
  • 切片不存具体的值,切片是一个引用类型。
  • 切片的本质就是对底层数组的封装,它包含了三个信息:底层数组的指针、切片的长度(len)和切片的容量(cap)。
  • 切片之间是不能比较的,我们不能使用==操作符来判断两个切片是否含有全部相等元素。 切片唯一合法的比较操作是和nil比较。 一个nil值的切片并没有底层数组,一个nil值的切片的长度和容量都是0。但是我们不能说一个长度和容量都是0的切片一定是nil
package main

import (
   "fmt"
)

func main() {
   s := make([]string, 3)
   s[0] = "a"
   s[1] = "b"
   s[2] = "c"
   fmt.Println("get:", s[2])
   fmt.Println("length:", len(s))
   s = append(s, "e", "f")
   fmt.Println(s)
   c := make([]string, len(s))
   copy(c, s)
   fmt.Println(c)
   fmt.Println(s[2:5])
   fmt.Println(s[:5])
   fmt.Println(s[2:])
   good := []string{"wmm", "fsfd", "ffedf", "fsffs"}
   fmt.Println(good)
}
  1. map
package main

import (
   "fmt"
)

func main() {
   m := make(map[string]int)
   m["one"] = 1
   m["two"] = 2
   m["three"] = 3
   fmt.Println(m)
   fmt.Println(m["one"], m["two"])
   fmt.Println(m["unknown"])
   r, ok := m["unknown"]
   fmt.Println(r, ok)
   delete(m, "one")
   fmt.Println(m)
   m2 := map[string]int{"one": 1, "two": 2}
   var m3 = map[string]int{"one": 1, "two": 2}
   fmt.Println(m2, m3)
}
  1. range
package main

import (
   "fmt"
)

func main() {
   nums := []int{2, 3, 4}
   sum := 0
   for i, num := range nums {
      sum += num
      if num == 2 {
         fmt.Println("index:", i, "num :", num)
      }
   }
   fmt.Println(nums)
   m := map[string]string{"one": "1", "two": "2"}
   for k, v := range m {
      fmt.Println(k, v)
   }
   for _, v := range m {
      fmt.Println(v)
   }
   for k := range m {
      fmt.Println(k)
   }
}
  1. 函数
package main

import (
   "fmt"
)

func main() {
   res := add(1, 2)
   fmt.Println(res)
   v, ok := exists(map[string]string{"A": "a"}, "A")
   fmt.Println(v, ok)
}
func add(a int, b int) int {
   return a + b
}
func add2(a, b int) int {
   return a + b
}
func exists(m map[string]string, k string) (v string, ok bool) {
   v, ok = m[k]
   return v, ok
}