Go语言快速入门| 青训营笔记

65 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

因为之前学校课程原因,导致笔记一直没有整理好发布。于是就等到过完年后,再一起整理发布了。 本篇文章,主要涉及Go语言的基础语法。如有错误,烦请指出。

GO语言的特点

  • 高性能、高并发
  • 语法简单、学习曲线平缓
  • 丰富的标准库
  • 完善的工具链
  • 静态链接
  • 快速编译
  • 跨平台
  • 垃圾回收

基础语法

变量

GO是强类型语言(即每个变量都有自己对应的变量类型)。

定义变量的方式

  • 通过var name string = “” 方式定义,GO会自己推断变量的类型,可以不指明类型;也可以在声明变量时指明。

    var x = "abcd" //不指明变量类型
    fmt.Println(reflect.TypeOf(x)) //stringvar y = 66 //指明变量类型
    fmt.Println(reflect.TypeOf(y)) //int
    
  • 使用变量 冒号 := 等于值。

    var x = "abcd"                 //不指明变量类型
    fmt.Println(reflect.TypeOf(x)) //stringvar y = 66                     //指明变量类型
    fmt.Println(reflect.TypeOf(y)) //int
    ​
    z := y + 100
    fmt.Println(z) //166
    

变量类型

  • 整型

    var b, c int = 1, 2
    

    go的整型数运算规则与大部分编程语言一致。

  • 浮点型

    var e float64
    ​
    f := float32(e)
    

    浮点型变量在定义时可以指定32位浮点数或者64位浮点数类型。

    初始值为0。

  • 布尔型

    var d = true
    
  • 字符串

    var a = "initial"
    ​
    g := a + "foo"
    ​
    fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0
    ​
    fmt.Println(g)                // initialapple
    

    go 语言的字符串是内置类型,可以直接通过加号拼接,也能够直接用等于号去比较两个字符串。

    在我的常用语言Java中,字符串并不能简单地用等于号去比较,而是要调用官方封装好的字符串方法。

常量

将var 改成const,即可定义常量。

go语言里面的常量,它没有确定的类型,会根据使用的上下文来自动确定类型。

const s string = "constant"
const h = 500000000
const i = 3e20 / h
fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
fmt.Println(reflect.TypeOf(h)) //int

if else

if 7%2 == 0 {
   fmt.Println("7 is even")
} else {
   fmt.Println("7 is odd")
}
​
if 8%4 == 0 {
   fmt.Println("8 is divisible by 4")
}
​
if num := 9; num < 0 {
   fmt.Println(num, "is negative")
} else if num < 10 {
   fmt.Println(num, "has 1 digit")
} else {
   fmt.Println(num, "has multiple digits")
}

Go语言的if else写法与别的语言区别不大,主要是以下两点区别:

  • if后面的条件判断语句不需要使用括号括起来
  • if以后的执行语句一定要使用括号括起来

循环

Go中只有一种循环体----for循环。

  • 最简单的for循环——死循环

    for {
       fmt.Println("loop")
       break
    }
    

    for后面没有任何条件判断。

  • 一般的for循环

    for j := 7; j < 9; j++ {
       fmt.Println(j)
    }
    

    j := 7 代表初始化

    j < 9 代表执行条件,不满足则跳出循环

    j++ 代表循环体执行完之后要进行的操作

  • break和continue

    • break:表示跳出整个for循环
    • continue:表示只是跳过当次循环

switch

Go语言中的switch语句体switch后面的变量并不需要括号。

另外一点与之不同的是,Go中的Switch中的每个case中的执行语句之后并不需要break就会自己结束switch语句的执行。

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")
}

除此之外,Go语言中的switch功能强大。可以在 switch 后面不加任何的变量,然后在 case 里面写条件分支,从而替代多个if else的代码块,增强代码逻辑。

t := time.Now()
switch {
case t.Hour() < 12:
   fmt.Println("It's before noon")
default:
   fmt.Println("It's after noon")
}

数组

Go中的数组与其他语言类似。

  • 第一种定义方式:使用var定义

    var a [5]int
    a[4] = 100
    fmt.Println("get:", a[2]) //0
    fmt.Println("len:", len(a)) //5
    
  • 第二种定义方式:直接使用:=赋值

    b := [5]int{1, 2, 3, 4, 5}
    fmt.Println(b)
    

切片

切片应该是Go中最常用的数据结构,类似Java中的List类。他们都可以自动扩充空间来存放数据。

  • make创建切片

    s := make([]string, 3)
    s[0] = "a"
    s[1] = "b"
    s[2] = "c"
    fmt.Println("get:", s[2])   // c
    fmt.Println("len:", len(s)) // 3
    

    使用make需要指定初始长度来创建切片。

  • append添加元素

    s = append(s, "d")
    s = append(s, "e", "f")
    fmt.Println(s) // [a b c d e f]
    

    值得注意的是:

    使用append后要将append后的结果重新赋值为原来的切片

    这是因为Go中的切片,存储的是一个长度和一个容量,还有一个指向数组的指针。

  • 取元素操作

    fmt.Println(s[2:5]) // [c d e]
    fmt.Println(s[:5])  // [a b c d e]
    fmt.Println(s[2:])  // [c d e f]
    

map

map 是实际使用过程中最频繁用到的数据结构。

  • 使用make创建map

    m := make(map[string]int)
    m["one"] = 1
    m["two"] = 2
    fmt.Println(m)           // map[one:1 two:2]
    fmt.Println(len(m))      // 2
    fmt.Println(m["one"])    // 1
    fmt.Println(m["unknow"]) // 0
    

    make(map[string]int):string表示key的类型是string;int表示value的类型是int。

  • 使用delete删除键值对

    delete(m, "one")
    

注意:

Go中的map存储键值对是完全无序的,打印的时候没有固定的顺序。

range

对于一个 slice 或者一个 map 的话,我们可以用 range 来快速遍历,这样代码能够更加简洁。range 遍历的时候,对于数组会返回两个值,第一个是索引,第二个是对应位置的值。如果我们不需要索引的话,我们可以用下划线来忽略。

nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
   sum += num
   if num == 2 {
      fmt.Println("index:", i, "num:", num) // index: 0 num: 2
   }
}
fmt.Println(sum) // 9
​
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
   fmt.Println(k, v) // b 8; a A
}
for k := range m {
   fmt.Println("key", k) // key a; key b
}

函数

Go函数与其他语言的不同之处在于:

  • 变量类型是后置的
  • 函数原生支持返回两个值:在实际的业务逻辑代码里面几乎所有的函数都返回两个值,第一个是真正的返回结果,第二个值是一个错误信息。
package main
​
import "fmt"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
}
​
func main() {
   res := add(1, 2)
   fmt.Println(res) // 3
​
   v, ok := exists(map[string]string{"a": "A"}, "a")
   fmt.Println(v, ok) // A True
}

文章最后,还有部分基础语法会在明天的笔记继续补充。谢谢阅读。