go基础语法
Go 语言的基础组成
- 包声明(Package Declaration) :Go语言的每个源文件都属于一个包。包声明指定了当前源文件所属的包,并决定了该文件中的代码在编译时如何组织和链接。
- 引入包(Import Packages) :通过引入其他包,我们可以使用其他包中定义的函数、变量和类型。使用
import关键字来引入包,并可通过import语句的方式引入多个包。 - 函数(Functions) :函数是Go语言中的基本执行单元。我们可以定义自己的函数,并通过函数名来调用它们。函数通常接收参数并返回一个值。
- 变量(Variables) :变量用于存储和操作数据。在Go语言中,我们需要先声明变量,然后才能使用它们。变量可以是基本类型(如整数、浮点数、字符串)或自定义类型。
- 语句和表达式(Statements & Expressions) :语句是执行特定操作的代码单元,例如赋值语句、条件语句和循环语句。表达式用于计算值,可以由常量、变量、运算符和函数调用等组成。
- 注释(Comments) :注释是对代码的解释和说明,对于开发者来说是很重要的。在Go语言中,我们可以使用
//来添加单行注释,或使用/* */来添加多行注释。
变量
-
Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。
-
Go语言是一门强类型语言,每一个变量都有它自己的变量类型
-
常见的变量类型
- 字符串
- 浮点型
- 整数型
- 布尔型
-
变量声明
-
指定变量类型,如果没有初始化,则变量默认为零值。
/* var v_name v_type //声明变量 v_name = value //赋值 */ var t1 string = "hello" var t2 int = 1 var t3 bool = true -
根据值自行判定变量类型。
/* var v_name = value */ var t1 = "hello" var t2 = 1 var t3 = true -
使用 := 声明变量
/* v_name := value */ t1 := "hello" t2 := 1 t3 := true -
多变量声明
//类型相同多个变量, 非全局变量 var vname1, vname2, vname3 type vname1, vname2, vname3 = v1, v2, v3 var vname1, vname2, vname3 = v1, v2, v3 // 和 python 很像,不需要显示声明类型,自动推断 vname1, vname2, vname3 := v1, v2, v3 // 出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误 // 这种因式分解关键字的写法一般用于声明全局变量 var ( vname1 v_type1 vname2 v_type2 )
-
常量
-
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
-
常量的定义格式
/* const identifier [type] = value */ // 显式类型定义: const t1 string = "abc" // 隐式类型定义: const t2 = "abc" // 多个相同类型的声明 const c_name1, c_name2 = value1, value2 -
常量还可以用作枚举
const ( t1 = iota t2 = 1 t3 = 2 )iota,特殊常量,可以认为是一个可以被编译器修改的常量。第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1
常用的数据类型
-
整数,int
支持的整型分类很细,主要差异是占用的存储空间不同。基于有无符号列出为:
- 有符号的:int,int8,int16,int32,int64
- 无符号的:uint,uint8,uint16,uint32,uint64
其中int, unit是基于处理器架构的。意味着会根据处理器来确定是32bit还是64bit。 使用时,常常使用int。或者使用int32保证兼容。 在类型推导时,推导的整型为int,其他长度整型需要在定义变量时强制声明。(整型的默认值为0)
-
浮点数,float
支持IEEE-754标准浮点数。支持32bit和64bit的浮点数float32和float64。 在类型推导时,推导的浮点型为float64。float32需要在定义变量时强制声明。(浮点数的默认值为0)
-
复数,complex
原生支持复数。 支持32bit+32bit复数complex64,和64bit+64bit的复数complex128。
// 定义复数 var t1 complex64 = complex(1, 2) var t2 complex128 = complex(1, 2) t3 := 1 + 2i t4 := complex(float64(1), float64(2)) // 获取实部和虚部 realPart := real(t1) imagPart := imag(t2) -
字符串,string
原生支持字符串。使用双引号("")或反引号(
)定义,内部是utf-8编码。 双引号:"", 用于单行字符串。 反引号:,用于定义多行字符串,内部会原样解析。 示例:// 单行 "test" // 多行 ` test test `字符串支持转义字符,列表如下: \r 回车符(返回行首) \n 换行符(直接跳到下一行的同列位置) \t 制表符 ' 单引号 " 双引号 \ 反斜杠 * \uXXXX Unicode字符码值转义
-
布尔型,bool
布尔型的值只可以是常量 true 或者 false
-
指针,pointer
指针类型用于存储变量地址。使用运算符
&,*完成操作。 使用运算符p:=&v可以获取v变量的地址。p中的数据格式类似0xc0000b9528,是一个内存地址的16进制表示。 使用运算符*p可以获取指针p指向变量v的值。在Go语言中,指针主要用于: 类型指针,对指针指向的数据进行修改。函数调用时传递参数使用指针,避免值传递拷贝额外数据。注意类型指针不能进行偏移和运算。 切片,由指向起始元素的原始指针、元素数量和容量组成。
-
数组,array
数组是一段固定长度的连续内存区域。是具有相同类型数据元素序列。元素类型支持任意内置类型。 数组从声明时就确定长度,可以修改数组元素,但是数组不可修改长度。 使用
[长度]类型进行数组的声明。 示例:// 默认值初始化 var nums [4]int // [0 0 0 0] // 数组常量初始化数组 var position = [4]string{"east", "south", "west", "north"} var arrAge = [5]int{18, 20, 15, 22, 16} var arrKeyValue = [5]string{3: "Chris", 4: "Ron"} // 自动确定长度 var position = [...]string{"east", "south", "west", "north"} -
切片,slice
-
切片可以看作是数组的引用,切片和数据对应的是同一份数据,如果原数组的数据发生变化,那么会连带着切片中的数据一起变化。
-
左闭右开
-
切片声明:var identifier []type
-
len()函数计算切片长度,cap()函数计算切片容量,append()函数进行切片追加,copy()函数进行拷贝
-
切片使用
-
从数组中产生切片
var a [10]int var s []int= a[:] s = a[:4] s = a[1:] -
直接定义切片
s := []int{1,2,3,4,5,6} -
make方法创建切片
/* make 的使用方式是:func make([]T, len, cap),其中 cap 是可选参数。 */ s := make([]int, 0, 5)
-
-
二维切片
mat := make([][]int, 10) for i := 0; i < 10; i++ { mat[i] = make([]int, 10) }
-
-
映射,map
-
Map 是一种无序的键值对的集合。
-
Map 是引用类型,如果将一个 Map 传递给一个函数或赋值给另一个变量,它们都指向同一个底层数据结构,因此对 Map 的修改会影响到所有引用它的变量。
-
定义map
/* 使用 make 函数 */ map_variable := make(map[KeyType]ValueType, initialCapacity)其中 KeyType 是键的类型,ValueType 是值的类型,initialCapacity 是可选的参数,用于指定 Map 的初始容量。Map 的容量是指 Map 中可以保存的键值对的数量,当 Map 中的键值对数量达到容量时,Map 会自动扩容。如果不指定 initialCapacity,Go 语言会根据实际情况选择一个合适的值。
-
获取元素:
// 获取键值对 v1 := m["apple"] v2, ok := m["pear"] // 如果键不存在,ok 的值为 false,v2 的值为该类型的零值 -
修改元素:
// 修改键值对 m["apple"] = 5 -
获取 Map 的长度:
// 获取 Map 的长度 len := len(m) -
遍历 Map:
// 遍历 Map for k, v := range m { fmt.Printf("key=%s, value=%d\n", k, v) } -
删除元素:
// 删除键值对 delete(m, "banana")
-
-
结构体,struct
-
Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。
-
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
-
定义结构体
结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:
type struct_variable_type_name struct { member definition member definition ... member definition } -
结构体方法
Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收器(Receiver)
func (接收器变量 接收器类型) 方法名(参数列表) (返回参数){ }接收器类型可以是带指针的与不带指针的,带指针的会对结构体修改
-
-
接口,interface
- interface 是方法声明的集合
- 任何类型的对象实现了在interface 接口中声明的全部方法,则表明该类型实现了该接口。
- interface 可以作为一种数据类型,实现了该接口的任何对象都可以给对应的接口类型变量赋值。
- interface 可以被任意对象实现,一个类型/对象也可以实现多个 interface
-
interface 定义的方法不能重载,如 eat() eat(s string) 不能同时存在
//Info 是一个接口,它有方法 Getinfo()string type Info interface { Getinfo() string }
-
函数,func()
-
函数定义
Go 语言函数定义格式如下:
func function_name( [parameter list] ) [return_types] { 函数体 }
-
Go语言函数支持递归使用
条件语句
-
if语句
if 布尔表达式 { ··· } -
if···else语句
if 布尔表达式 { ··· }else 布尔表达式{ ··· } -
Switch语句
switch var1 { case val1: ... case val2: ... default: ... }与C语言不同的是,Go语言中的switch 默认情况下 case 最后自带 break 语句,匹配成功后就不会执行其他 case
循环语句
-
格式
// 1、类似C语言的for循环 for init; condition; post { } // 2、类似C语言的while循环 for condition {} // 3、死循环 for {} // 4、可以使用for与range对 slice、map、数组、字符串等进行遍历 for key, value := range oldMap { newMap[key] = value }
- 与C语言类似可以使用break跳出循环,使用continue继续循环