GoLang基础语法 | 青训营笔记

251 阅读3分钟

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

一、本堂课重点内容

  • Hello World
  • 变量与变量类型
  • 分支循环
  • 数组与切片
  • map
  • 函数

二、详细知识点介绍

Hello World

  GoLang 程序的 基本结构如下:

// hello.go
package main    // 当前文件所在的包

import "fmt"    // 导入外部包

func main() {
    /* 
        这是多行注释
    */
    fmt.Println("Hello, World!")
    fmt.Println("Hello, World!")
    // 介是单行注释
}

  运行该程序可以直接go run hello.go,或者先编译再运行,即go build -o hello hello.go && ./hello

  1. GoLang 语句后不需要分号
  2. 对于函数、循环体等的代码块,大括号不可以出现在新行

变量

  GoLang 是一门静态强类型语言,GoLang 的内置变量类型包括整型(int)、浮点型(float,float64)、字符串(string)等。GoLang 声明变量的方式如下:

// 显式声明,不初始化赋值0
var var0 double = 3.14
var var1, var2 int = 1, 2
var (
    v0 int = 0;
    v1 double = 2.7
)
// 根据赋值自动确定类型
var var2 = 2.0
// 省略 var,不可用于声明全局变量
name := "Go"

  可使用const定义常量,可使用constiota方便地定义枚举:

const ca int = 1
// iota 初始为0,逐行递增
const (
    a, b = iota, iota+1            // 0, 1 
    c, d                           // 1, 2
    e, f = iota * 10, iota * 20    // 20, 40
    g, h                           // 30, 60
)
  1. GoLang 是一门静态强类型语言,因此已经赋值的变量的类型已经确定,无法赋予其他类型的值。

分支循环

条件判断

  GoLang 的 if else和 C++ 的类似,但 GoLang 的条件语句不需要括号,如:

if 3 % 2 == 0 {
    fmt.Println("3 是偶数")
} else if 3 % 2 == 1 {
    fmt.Println("3 是奇数")
} else {
    fmt.Println("3 是啥?猫猫不造诶")
}

循环

  GoLang 没有while循环和 do while循环,只有各式各样的for循环:

  没有任何其他条件的是死循环:

i := 0
for {
    fmt.Println("i = ", i)
    i++
}

  可以使用类似 C++ 的 for 循环结构:

for i := 0; i < 5 i++ {
    fmt.Println("i = ", i)
}

实际生产中起始条件和循环后置操作常常省略,可以使用类似while循环的循环:

i := 0
for i < 5 {
    fmt.Println("i = ", i)
    i++
}

  与 C++ 相同,GoLang 也可以使用 continuebreak

switch case

  GoLang 的 switch case与 C++ 类似:

switch score / 10 {
    case 10:
        fmt.Println("恭喜你考了100分,等级为A!")
    case 9:
        fmt.Println("你的等级为A")
    case 8:
        fmt.Println("你的等级为B")
    case 7:
        fmt.Println("你的等级为C")
    case 6:
        fmt.Println("你的等级为D")
    case 5, 4, 3, 2, 1, 0:
        fmt.Println("很遗憾,你没有及格")
}

  GoLang 的switch case可以使用任意的变量类型,也可以省略 switch 后的变量,每个 case 作为一个独立的分支判断(但只执行第一个符合条件的)。

数组与切片

  GoLang 中普通数组的使用方法如下:

var myArray [10]int
myArray = [10]int{1, 2, 3, 4}
for i := 0; i < len(myArray); i++ {
	println(myArray[i])
}
for index, value := range myArray {
	println("index = ", index, ", value = ", value)
}

  将这种数组作为函数实参时,函数必须指定数组长度,且为深拷贝传递,非常不适合开发,因此我们需要“动态数组”——切片(slice):

var mySlice = []int{1, 2, 3, 4}
mySlice = append(mySlice, 5, 6)
for _, value := range mySlice {
	println("value = ", value)
}
var slice0 = make([]int, 3, 5)
// 类型、初始化范围、容量,可不指定容量
slice0[2] = 2
fmt.Printf("len = %d, cap = %d, value = %v\n", len(slice0), cap(slice0), slice0)
slice0 = append(slice0, 5)
// slice0[3] = 5 不可行,因为未初始化
fmt.Printf("len = %d, cap = %d, value = %#v\n", len(slice0), cap(slice0), slice0)
slice0 = append(slice0, 1, 9, 5)
// 昂会增加到原来的两倍,可用范围不翻倍
fmt.Printf("len = %d, cap = %d, value = %#v\n", len(slice0), cap(slice0), slice0)

  类似 Python的列表(List),Go 的 slice 也可以“切片”(名称怪怪的):

var slice = []int{1, 2, 3, 4, 5}
fmt.Printf("slice[1:3] = %v\n", slice[1:3])
// slice[1:3] = [2 3]
fmt.Printf("slice[:3] = %v\n", slice[:3])
// slice[:3] = [1 2 3]
fmt.Printf("slice[1:] = %v\n", slice[1:])
// slice[1:] = [2 3 4 5]
  1. slice[start:end]:参数表示下标,左开右闭区间
  2. 可以使用大于最大下标的参数来截取到末尾
  3. 不支持负数下标

  对 slice 的操作是操作引用,可以使用copy(slice2, slice)将 slice 的内容拷贝给 slice2

map

  GoLang 的 map 就是个 map,使用方法如下:

myMap := make(map[string]int, 3)
myMap2 := map[string]int{
	"code":   1,
	"height": 180,
	"weight": 60,
}
// 赋值
myMap["code"] = 1
// 删除
delete(myMap, "code")
  1. map 中的数据不会自动排列,其顺序是随机的
  2. 也可以使用 range 来遍历 map

函数

  与多数编程语言不同, Go 支持具有多个返回值的函数。函数的定义格式如下:

func swap(a int, b int) (int, int){
    return b, a
}
  1. 返回值列表中可以指定变量名,此时只要在函数结束前给这些变量赋值即可
  2. 可以在一个函数中使用defer指定函数返回后进行的操作,这些操作按照定义的顺序的相反顺序执行,

本文若有不足之处,欢迎纠正(≧^.^≦)喵~

我的其他笔记,可在掘金或 Github( github.com/DoudiNCer/I… )阅读