Go语言基础 | 青训营笔记

55 阅读3分钟

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

Go语言基础

简介

Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言

Go语言最主要的特性:

  • 自动垃圾回收
  • 更丰富的内置类型
  • 函数多返回值
  • 错误处理
  • 匿名函数和闭包
  • 类型和接口
  • 并发编程
  • 反射
  • 语言交互性

代码注意要点

  1. 程序入口必须是main包的main函数
  2. 每行结尾不必打 ;
  3. if 表达式, for 表达式不必打 ()
  4. 定义的变量等必须要使用,否则编译不通过(全局变量除外)
  5. 包中写的函数或变量名若首字母大写,则包外可访问,否则只能包内访问
  6. ......

Go语言数据类型

  1. bool类型: true false
  2. 数字类型: byte int int8 int16 int32 rune uint8 uint16 uint32 uint64 int64 uint float32 float64 complex64(32位实数和虚数, 默认值是0+0i) complex128(64位实数和虚数, 默认值是0+0i) uintptr(无符号整型,用于存放指针)
  3. 字符串类型: 由单个字节连接起来
  4. 派生类型: 指针、数组、结构体、Channel、函数、切片、接口、Map

Go语言变量与常量

单独声明一个变量

var value1 int
var value2 int = 3
var value3 = 4

声明多个变量

var value1, value2, value3 int
var value4, value5, value6 = 1, 2, 3

简短形式,:=操作符

value1 := 2
value2, value3, value4 := 1, 2, 3

常量声明

const str1 string = "abc"
const str2 = "abcde"
const str3, str4, str5 = "aa", "bb", "cc"
fmt.Printf(len(str2)) //5

fmt.Printf(unsafe.Sizeof(str2)) //16
//string类型在 go 里是个结构, 包含指向底层数组的指针和长度,这两部分每部分都是8个字节,
//所以字符串类型大小为 16 个字节。

const枚举

//iota,特殊常量,可以认为是一个可以被编译器修改的常量,当const关键词出现时,重置为0,每增一行iota+1,可以看做行索引
const (
   n1 = iota //0
   n2        //1
   _         //2,抛弃
   n4        //3
   n5 = 100  //100
   n6        //100, 会延续上一行
   n7 = iota //6
)

条件语句

if语句

if(/*表达式*/) {

} else if {

} else {

}

switch 语句

grade := 98
switch {
case grade >= 90:
   fmt.Println("A") //不必加break
case grade >= 80:
   fmt.Println("B")
case grade >= 70:
   fmt.Println("C")
case grade >= 60:
   fmt.Println("D")
default:
   fmt.Println("E")
}

x := 2
switch x {
default:
   fmt.Println("default语句放哪都最后执行")
case 1, 4, 5: //允许的操作
   fmt.Println("1.条件语句是false")
   fallthrough
case 2:
   fmt.Println("2.条件语句是true")
   fallthrough //强制执行下一条case语句
case 3:
   fmt.Println("3.条件语句是false")
}

select语句

  1. select 是 Go 中的一个控制结构,类似于 switch 语句。

  2. select 语句只能用于通道操作,每个 case 必须是一个通道操作,要么是发送要么是接收。

  3. select 语句会监听所有指定的通道上的操作,一旦其中一个通道准备好就会执行相应的代码块。

  4. 如果多个通道都准备好,那么 select 语句会随机选择一个通道执行。如果所有通道都没有准备好,那么执行 default 块中的代码。

循环语句

PS: Go语言的循环只有for关键字

无限循环

for {

}

for true {

}

循环体

for int i = 1; i <= 10; i++ {

}

range : range 可以对数组、字符串、map(集合)、slice(切片)、channel(通道) 迭代循环

num := []int{1, 2, 3, 4, 5}
for index, value := range num{ 
   fmt.Println("num1[", index, "]=", value)
}
fmt.Println(num) //[1 2 3 4 5]

goto 语句

在变量 a 等于 15 的时候跳过本次循环并回到循环的开始语句 LOOP 处:

var a int = 10  
   /* 循环 */  
   LOOP: for a < 20 {  
      if a == 15 {  
         /* 跳过迭代 */  
         a = a + 1  
         goto LOOP  
      }  
      fmt.Printf("a的值为 : %d\n", a)  
      a++      
   }

数组

声明数组

var num[10]int
var num[10][10]int //二维数组

声明同时初始化数组

var num[10]string = {"1","2","3"} //其他未声明值为空""
num = []int {1,2,3,4,5}

向二维数组中添加一维数组

arr := [][]int{}
num1 := []int{1, 2, 3, 4, 5}
num2 := []int{5, 4, 3, 2, 1}
arr = append(arr, num1)
arr = append(arr, num2)

指针

value := 9
var ptr *int
ptr = &value
fmt.Println(*ptr) //9

切片

slices := make([]int, 10, 100) //10为数组长度len、100为最大容量cap

s := slices[0:10]   //以另一切片或数组 0~10初始化切片
fmt.Println(s[1:2]) //截取切片 :10   0:  :

slices = append(slices, 1, 2, 3)                         //切片添加元素
newSlices := make([]int, len(slices), (2 * cap(slices))) //扩容到两倍
copy(newSlices, slices) //把slices内容拷贝到newSlices

Map(集合)

//map
//var mapTest1 map[string]string //声明
mapTest1 := map[string]string{"1": "own", "2": "two", "3": "three"}
fmt.Println(mapTest1)

mapTest2 := make(map[int]string)
mapTest2[1] = "own"
mapTest2[2] = "two"
mapTest2[3] = "three"
mapTest2[4] = "four"
for key, value := range mapTest2 {
   fmt.Printf("%v->%v\n", key, value)
}
number, english := mapTest2[2]
if english {
   fmt.Println("存在", number)
} else {
   fmt.Println("不存在对应value值")
}
delete(mapTest2, 4) //删除key值对应的key-value对

函数

Go语言的函数可以没有返回值,也可以有多个返回值

普通函数

func 函数名(参数列表) (返回值列表,可无) {

}

func numbers() (int, int, string) {
   return 1, 2, "3"
}

对象的成员函数

fuc (object Type) (参数列表) (返回值) {
}

err错误

func sum(f1, f2 float64) (float64, error) {
   return f1 + f2, errors.New("加法错误")
}