GoLang学习笔记

发布于:2025-07-24 ⋅ 阅读:(17) ⋅ 点赞:(0)

Go语言定义变量

常见定义方法

  • 使用var:语法为var 变量名类型= 表达式,例如var name string = "zhangsan"
  • 类型推导(函数内部):语法为变量名:= 表达式,例如n := 10;注意短变量只能用于声明局部变量,不能用于全局变量声明

fmt 包及打印方法

  1. 使用前提:需要引入 fmt 包,即import "fmt"
  2. Print 与 Println 的区别
    • 多值输入时,Println 会在值中间加空格,Print 不会,例如fmt.Println("go", "python", "php", "javascript")输出为go python php javascriptfmt.Print("go", "python", "php", "javascript")输出为gopythonphpjavascript
    • 换行方面,Println 会自动换行,Print 不会,例如连续使用fmt.Println("hello")fmt.Println("world"),输出结果为分行的helloworld;而连续使用fmt.Print("hello")fmt.Print("world"),输出结果为helloworld
  3. Println 与 Printf 的区别:Printf 是格式化输出,需使用占位符,如%d表示数字的十进制表示,且占位符与后面的变量一一对应,使用更灵活;例如fmt.Printf("a=%d,b=%d,c=%d", a, b, c)可输出a=10,b=20,c=30,而fmt.Println("a=", a, ",b=", b, ",c=", c)输出为a= 10 ,b= 20 ,c= 30
  4. 更多占位符参考:可访问http://docscn.studygolang.com/pkg/fmt/

注释

快捷注释方式:Windows 系统使用ctrl+/,Mac 系统使用command+/

  1. 注释形式
    • 多行注释:/* 这是一个注释 */
    • 单行注释:// 这是一个注释

Go 变量、常量及命名规则

变量声明方式

  • 使用var声明:语法为var 变量名称 type,如var name stringvar age int等;也可在声明时赋值,如var username="张三"var age int =20
  • 一次定义多个变量:var identifier1, identifier2 type,如var username, sex string;也可在声明时赋值,如var a, b, c, d = 1, 2, 3, false
  • 批量声明变量并可指定类型或赋值:如var (a string; b int; c bool),也可在批量声明时直接赋值,如var (a string = "张三"; b int = 20; c bool = true)
  • 变量初始化:声明时会自动初始化为类型默认值,如整型和浮点型默认值为 0,字符串为空字符串等;也可手动指定初始值,标准格式为var 变量名类型= 表达式,还可一次初始化多个变量,如var name, age = "zhangsan", 20
  • 类型推导:省略变量类型,编译器根据等号右边值推导类型,如var name = "Q1mi"
  • 短变量声明法:函数内部用:=声明并初始化局部变量,不能用于全局变量,如n := 10,也可一次声明多个,如m1, m2, m3 := 10, 20, 30
  • 匿名变量:用_表示,用于忽略多重赋值中的某个值,不占用命名空间,无重复声明问题,如_, username := getInfo()
  • 注意事项:函数外语句须以关键字开头;:=不能在函数外使用;_多用于占位忽略值

常量

  1. 定义:恒定不变的值,声明类似变量但用const,定义时必须赋值,如const pi = 3.1415;可同时声明多个,如const (pi = 3.1415; e = 2.7182);同时声明多个时省略值则与上一行相同,如const (n1 = 100; n2; n3)中 n2、n3 均为 100。
  2. 结合 iota 使用:iota 是常量计数器,仅在常量表达式中使用,const 出现时重置为 0,每新增一行常量声明计数一次。如const a = iota中 a=0;可跳过某些值、中间插队、多个定义在一行等,如const (n1 = iota; n2 = 100; n3 = iota)中 n1=0、n2=100、n3=2

命名规则

  1. 由数字、字母、下划线组成,开头不能是数字。
  2. 不能是保留字和关键字。
  3. 区分大小写,不建议用大小写区分两个变量。
  4. 见名思意,变量用名词,方法用动词。
  5. 一般用驼峰式,特有名词根据私有性全大写或小写。

代码风格

  1. 每行结束不用写分号。
  2. 运算符左右建议各加一个空格。
  3. 推荐驼峰式命名。
  4. 左括号须紧接着语句不换行。
  5. 可用go fmt格式化文档统一风格

Go 语言基本数据类型

一、数据类型总体介绍

Go 语言数据类型分为基本数据类型和复合数据类型。

  • 基本数据类型:整型、浮点型、布尔型、字符串。
  • 复合数据类型:数组、切片、结构体、函数、map、通道 (channel)、接口等。

二、整型

  1. 分类

    • 有符号整型:按长度分为 int8、int16、int32、int64,分别对应不同范围(如 int8 范围为 - 128 到 127),占用空间依次为 1、2、4、8 个字节。
    • 无符号整型:对应有符号整型,为 uint8、uint16、uint32、uint64,范围从 0 开始(如 uint8 为 0 到 255),占用空间同对应有符号类型。
  2. 特殊整型

    • uint:32 位系统上为 uint32,64 位系统上为 uint64;int:32 位系统上为 int32,64 位系统上为 int64;uintptr:无符号整型,用于存放指针。
    • 注意:使用 int 和 uint 时需考虑平台差异,涉及二进制传输等场景避免使用。
  3. 相关操作

    • 查看变量占用字节数:使用unsafe.Sizeof(n1)(需引入 unsafe 包)。
    • 类型转换:不同长度整型可显式转换,如num2 := int32(num1)(num1 为 int8)。
    • 数字字面量语法:Go1.13 后支持二进制(0b 前缀)、八进制(0o 前缀)、十六进制(0x 前缀)定义,可使用_分隔数字(如v := 123_456)。

 

注意: 在使用 int uint 类型时,不能假定它是 32 位或 64 位的整型,而是考虑 int uint
可能在不同平台上的差异。
注意事项:实际项目中整数类型、切片、 map 的元素数量等都可以用 int 来表示。在涉及
到二进制传输、为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使
int uint

 

三、浮点型

  1. 类型:float32(最大范围约 3.4e38)和 float64(最大范围约 1.8e308),默认类型为 float64。
  2. 打印:使用fmt.Printf配合%f(默认保留 6 位小数)或%.2f(保留 2 位小数)等占位符。
  3. 精度问题:存在二进制浮点数精度丢失问题(如8.2 - 3.8结果为 4.399999999999999),可使用第三方包(如github.com/shopspring/decimal)解决。
  4. 科学计数法:如5.1234e2(5.1234×10²)、5.1234E-2(5.1234÷10²)。

四、布尔值

  • 类型为 bool,值只有 true 和 false,默认值为 false。
  • 注意:不允许将整型强制转换为布尔型,布尔型无法参与数值运算或与其他类型转换。

五、字符串

  1. 基本特性:以原生数据类型出现,内部使用 UTF-8 编码,值用双引号包裹,可包含非 ASCII 字符(如s2 := "你好")。

  2. 转义符:包括\r(回车)、\n(换行)、\t(制表符)、\'(单引号)、\"(双引号)、\\(反斜杠)等。

  3. 多行字符串:使用反引号(`)定义,换行原样保留,转义符无效。

  4. 常用操作

    • 长度:len(str)
    • 拼接:+fmt.Sprintf
    • 分割:strings.Split
    • 包含判断:strings.Contains
    • 前缀 / 后缀判断:strings.HasPrefix/strings.HasSuffix
    • 子串位置:strings.Index(从前往后)、strings.LastIndex(从后往前)。
    • 拼接切片:strings.Join

六、byte 和 rune 类型

  1. byte:即 uint8,代表 ASCII 码字符。
  2. rune:即 int32,代表 UTF-8 字符,用于处理中文、日文等复合字符。
  3. 区别与应用:一个字母占 1 个字节(byte),一个汉字占 3 个字节;遍历字符串时,for i := 0; i < len(s); i++按 byte 遍历(可能乱码),for _, r := range s按 rune 遍历(正确处理中文)。

七、修改字符串

需先转换为[]rune(处理中文)或[]byte(处理 ASCII),修改后再转回 string,转换会重新分配内存。例如:

s1 := "big"
byteS1 := []byte(s1)
byteS1[0] = 'p'
fmt.Println(string(byteS1)) // 输出"pig"

 GoLang 基本数据类型转换

一、数据类型转换概述

Go 语言中只有强制类型转换,没有隐式类型转换。

二、数值类型之间的相互转换

  1. 包含类型:整型和浮点型。
  2. 转换规则:不同数值类型进行运算时,需转换为相同类型才能运行,例如var a int8 = 20var b int16 = 40,需将a转换为int16类型才能进行加法运算。
  3. 注意事项:建议从低位类型转换为高位类型,高位类型转换为低位类型可能会出现溢出,导致结果错误,如var a int16 = 129,转换为int8类型后结果为-127
  4. 应用场景:在使用某些函数时,需将参数转换为函数要求的类型,如使用math包的Sqrt()函数计算直角三角形斜边长时,需将int类型的变量转换为float64类型。

三、其他类型转换成 String 类型

  1. 使用fmt.Sprintf:需注意不同类型对应的格式,int%dfloat%fbool%tbyte%c
  2. 使用strconv
    • intstring:使用strconv.Itoa函数。
    • floatstring:使用strconv.FormatFloat函数,需指定格式化类型、保留的小数位数等参数。
    • boolstring:使用strconv.FormatBool函数。
    • int64string:使用strconv.FormatInt函数,需指定进制。

四、String 类型转换成数值类型

  1. 转换成int类型:使用strconv.ParseInt函数,需指定字符串、进制和位数。
  2. 转换成float类型:使用strconv.ParseFloat函数,需指定字符串和位数。
  3. 转换成bool类型:使用strconv.ParseBool函数,不过实际意义不大。
  4. 转换成字符:可通过遍历字符串实现

五、特殊说明

在 Go 语言中,数值类型和bool类型不能相互转换

GoLang 中的运算符

一、内置运算符类型

Golang 内置的运算符包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符。

二、算术运算符

  1. 常用运算符:包括加(+)、减(-)、乘(*)、除(/)、求余(%,公式为被除数 - (被除数 / 除数)* 除数)。
  2. 特殊说明:++(自增)和 --(自减)在 Go 语言中是单独的语句,并非运算符;且只能独立使用,没有前 ++ 和前 -- 的用法,例如a = i++++i都是错误的,正确写法是i++
  3. 除法特点:若运算数都是整数,结果会去掉小数部分,保留整数部分,如10/3结果为 3;若有浮点数参与,结果为浮点数,如10.0/3结果约为 3.3333333333333335

 

短路特性:对于&&,若左边操作数为 False,右边操作数不会执行;对于||,若左边操作数为 True,右边操作数不会执行

 

Go 语言中的流程控制

一、流程控制概述

Go 语言中常用的流程控制有 if 和 for,switch 和 goto 主要用于简化代码、降低重复代码,属于扩展类流程控制

二、if else(分支结构)

  1. 基本写法:格式为if 表达式1 {分支1} else if 表达式2 {分支2} else {分支3},当表达式 1 为 true 时执行分支 1,否则判断表达式 2,满足则执行分支 2,都不满足则执行分支 3。
  2. 注意事项:与 if 匹配的左括号{必须与 if 和表达式在同一行,与 else 匹配的{必须与 else 在同一行,else 也必须与上一个 if 或 else if 右边的大括号在同一行。
  3. 特殊写法:可在 if 表达式前添加执行语句,再根据变量值判断,如if score := 56; score >= 90 {…},其中变量作用域仅限于该 if 语句内。

三、for(循环结构)

  1. 基本格式for 初始语句;条件表达式;结束语句{循环体语句},条件表达式为 true 时循环,为 false 时退出。
  2. 变体形式
    • 省略初始语句(需保留分号):如i := 0; for ; i < 10; i++ {…}
    • 省略初始语句和结束语句:类似 while 循环,如i := 0; for i < 10 {…; i++}
    • 无限循环:for {循环体语句},可通过 break、goto 等强制退出。

四、for range(键值循环)

可遍历数组、切片、字符串、map 及通道,返回值规律如下:

  • 数组、切片、字符串返回索引和值。
  • map 返回键和值。
  • 通道只返回通道内的值。
    例如遍历字符串:str := "abc 上海"; for index, val := range str {…}

五、switch case

  1. 基本用法:方便对大量值进行条件判断,每个 switch 只能有一个 default 分支。
  2. 特点:case 语句可不写 break,不会出现穿透现象;一个分支可包含多个值,用逗号分隔;也可在 switch 后不跟变量,直接在 case 中用表达式判断。
  3. fallthrough:可执行满足条件的 case 的下一个 case,默认穿透一层,如case s == "a": fmt.Println("a"); fallthrough; case s == "b": fmt.Println("b")会输出 a 和 b。

六、break(跳出循环)

  1. 作用场景:用于循环中跳出循环;在 switch 中执行一条 case 后跳出;多重循环中可通过标号 label 指定要跳出的循环。
  2. 示例:如lable2: for i := 0; i < 2; i++ {for j := 0; j < 10; j++ {if j == 2 {break lable2}}}

七、continue(继续下次循环)

用于 for 循环内结束当前循环,开始下一次迭代;添加标签时,开始标签对应的循环。

八、goto(跳转到指定标签)

通过标签无条件跳转,可简化跳出循环等操作,如if n > 20 {goto label1}; ...; label1: ...

Golang 中的数组

一、数组介绍

数组是一系列同一类型数据的集合,每个数据称为数组元素,包含的元素个数为数组长度。在 Golang 中,数组是长度固定的数据类型,长度是类型的一部分,例如[5]int[10]int是不同类型;数组元素占用连续内存地址,索引访问速度快。与数组对应的是 Slice(切片),切片更灵活,但理解数组是理解切片的基础。

二、数组定义

定义格式为var 数组变量名[元素数量]T,其中元素数量必须是常量,且一旦定义长度不可变。例如var a [5]int定义了一个长度为 5、元素类型为 int 的数组,[5]int[4]int是不同类型,不能相互赋值。数组通过下标访问,下标从 0 开始,最后一个元素下标为len-1,访问越界会触发 panic。

三、数组的初始化

  1. 方法一:使用初始化列表设置元素值,如var numArray = [3]int{1, 2}初始化后为[1 2 0],未指定的元素为对应类型零值。
  2. 方法二:让编译器根据初始值个数推断长度,用...代替长度,如var cityArray = [...]string{"北京", "上海", "深圳"},其类型为[3]string
  3. 方法三:指定索引值初始化,如a := [...]int{1: 1, 3: 5},结果为[0 1 0 5],类型为[4]int

四、数组的遍历

  1. for 循环遍历:通过下标访问,如for i := 0; i < len(a); i++ { fmt.Println(a[i]) }
  2. for range 遍历:返回索引和值,如for index, value := range a { fmt.Println(index, value) }

五、数组是值类型

数组赋值和传参会复制整个数组,修改副本不会影响原数组。数组支持==!=操作符,因内存总是被初始化。[n]*T表示指针数组,*[n]T表示数组指针。

六、多维数组

以二维数组为例,定义格式为var 数组变量名[元素数量][元素数量]T,如a := [3][2]string{{"北京", "上海"}, {"广州", "深圳"}, {"成都", "重庆"}}。遍历可使用嵌套 for range,如外层遍历获取每行,内层遍历获取每行元素。注意多维数组只有第一层可使用...推导长度,内层不可。


网站公告

今日签到

点亮在社区的每一天
去签到