[后端实践]Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题

60 阅读7分钟

Go语言简介

什么是Go语言

Go语言(或 Golang)是Google开发的开源编程语言,诞生于2006年1月2日下午15点4分5秒,于2009年11月开源,2012年发布Go稳定版。Go语言在多核并发上拥有原生的设计优势,Go语言从底层原生支持并发,无须第三方库、开发者的编程技巧和开发经验。

Go语言有如下特性:

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

哪些公司在使用Go语言

字节跳动,腾讯,美团,滴滴,百度,Google,Facebook,七牛云,哔哩哔哩,PingCAP等。

Go语言开发环境

安装Golang可以从下面三个网址下载:

  1. go.dev/
  2. studygolang.com/dl
  3. goproxy.cn/

Golang的IDE可以使用VsCode或者Goland。

Go语言基础语法

内置类型

  1. 值类型:
 bool
 int(32 or 64), int8, int16, int32, int64
 uint(32 or 64), uint8(byte), uint16, uint32, uint64
 float32, float64
 string
 complex64, complex128
 array    -- 固定长度的数组
  1. 引用类型(指针类型)
 slice   -- 序列数组(最常用)
 map     -- 映射
 chan    -- 管道

内置函数

append          -- 用来追加元素到数组、slice中,返回修改后的数组、slice
close           -- 主要用来关闭channel
delete            -- 从map中删除key对应的value
panic            -- 停止常规的goroutine  (panicrecover:用来做错误处理)
recover         -- 允许程序定义goroutine的panic动作
imag            -- 返回complex的实部   (complexreal imag:用于创建和操作复数)
real            -- 返回complex的虚部
make            -- 用来分配内存,返回Type本身(只能应用于slice, map, channel)
new                -- 用来分配内存,主要用来分配值类型,比如intstruct。返回指向Type的指针
cap                -- capacity是容量的意思,用于返回某个类型的最大容量(只能用于切片和 mapcopy            -- 用于复制和连接slice,返回复制的数目
len                -- 来求长度,比如string、array、slice、map、channel ,返回长度
printprintln     -- 底层打印函数,在部署环境中建议使用 fmt 包

内置接口

type error interface { //只要实现了Error()函数,返回值为String的都实现了err接口

	Error()    String

}

main函数

Go语言程序的默认入口函数(主函数):func main()
函数体用{}一对括号包裹。

func main(){
	//函数体
}

变量和常量

  1. 变量声明

Go语言中的变量需要声明后才能使用,同一作用域内不支持重复声明。并且Go语言的变量声明后必须使用。

Go语言的变量声明格式为:

var 变量名 变量类型

每声明一个变量就需要写var关键字会比较繁琐,go语言中还支持批量变量声明:

var (
    a string
    b int
    c bool
    d float32
)
  1. 变量的初始化

Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 布尔型变量默认为false。 切片、函数、指针变量的默认为nil

当然我们也可在声明变量的时候为其指定初始值。变量初始化的标准格式如下:

var 变量名 类型 = 表达式

或者一次初始化多个变量:

 var name, sex = "pprof.cn", 1
  1. 类型推导

有时候我们会将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化。例如:

var name = "pprof.cn"
var sex = 1
  1. 短变量声明

在函数内部,可以使用更简略的 := 方式声明并初始化变量。例如:

package main

import (
    "fmt"
)
// 全局变量m
var m = 100

func main() {
    n := 10
    m := 200 // 此处声明局部变量m
    fmt.Println(m, n)
}
  1. 常量的声明

相对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,只是把var换成了const,常量在定义的时候必须赋值。例如:

const pi = 3.1415
const e = 2.7182

多个常量也可以一起声明:

const (
    pi = 3.1415
    e = 2.7182
)

数组Array

Go语言的数组有如下特点:

  1. 数组:是同一种数据类型的固定长度的序列。
  2. 数组定义:var a [len]int,比如:var a [5]int,数组长度必须是常量,且是类型的组成部分。一旦定义,长度不能变。
  3. 长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型。
  4. 数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1 for i := 0; i < len(a); i++ { } for index, v := range a { }
  5. 访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic
  6. 数组是值类型,赋值和传参会复制整个数组,而不是指针。因此改变副本的值,不会改变本身的值。
  7. 支持 "=="、"!=" 操作符,因为内存总是被初始化过的。
  8. 指针数组 [n]*T,数组指针 *[n]T。

数组初始化

  1. 一维数组初始化
  全局:
  var arr0 [5]int = [5]int{1, 2, 3}
  var arr1 = [5]int{1, 2, 3, 4, 5}
  var arr2 = [...]int{1, 2, 3, 4, 5, 6}
  var str = [5]string{3: "hello world", 4: "tom"}
  局部:
  a := [3]int{1, 2}           // 未初始化元素值为 0。
  b := [...]int{1, 2, 3, 4}   // 通过初始化值确定数组长度。
  c := [5]int{2: 100, 4: 200} // 使用索引号初始化元素。
  d := [...]struct {
  	name string
  	age  uint8
  }{
  	{"user1", 10}, // 可省略元素类型。
  	{"user2", 20}, // 别忘了最后一行的逗号。
  }
  1. 多维数组初始化
 全局
 var arr0 [5][3]int
 var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
 局部:
 a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
 b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能用 "..."。

流程控制

  1. if语句
  • 可省略条件表达式括号。

  • 持初始化语句,可定义代码块局部变量。

  • 代码块左括号必须在条件表达式尾部。

    if 布尔表达式 { /* 在布尔表达式为 true 时执行 / } else { / 在布尔表达式为 false 时执行 */ }

  1. switch语句

switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上直下逐一测试,直到匹配为止。 Golang switch 分支表达式可以是任意类型,不限于常量。可省略 break,默认自动终止。例如:

switch var1 {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}
  1. for循环
for init; condition; post { }
for condition { }
for { }
init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。
for语句执行过程如下:
①先对表达式 init 赋初值;
②判别赋值表达式 init 是否满足给定 condition 条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,不满足条件,就终止for循环,执行循环体外语句。

函数

Go语言函数有如下特点:

• 无需声明原型。
• 支持不定 变参。
• 支持多返回值。
• 支持命名返回参数。 
• 支持匿名函数和闭包。
• 函数也是一种类型,一个函数可以赋值给变量。
• 不支持 嵌套 (nested) 一个包不能有两个名字一样的函数。
• 不支持 重载 (overload) 
• 不支持 默认参数 (default parameter)。

函数声明:

func test(x, y int, s string) (int, string) {
    // 类型相同的相邻参数,参数类型可合并。 多返回值必须用括号。
    n := x + y          
    return n, fmt.Sprintf(s, n)
}