go 基础知识总结
创始人
2024-06-02 17:53:42
0

1 ctrl+shift+d 调试

2 ctrl+shift+x 管理扩展

3 设置自动补全

go env -w GOPROXY=https://goproxy.cn,direct

Windows平台按下Ctrl+Shift+P,Mac平台按Command+Shift+P,这个时候VS Code界面会弹出一个输入框,如下图:>go:install Go:Install/Update Tools

设置自动保存

文件 首选项 设置 afterdelay

4 查看错误和警告 ctrl+shift+M

5切换集成终端 ctrl+·

setting.json

“go.useCodeSnippetsOnFunctionSuggest”: true

6正上方会出现一个框 Ctrl+Shift+P 弹出命令行

如果你的Windows使用的是cmd,那么按如下方式指定环境变量。

SET CGO_ENABLED=0  // 禁用CGO
SET GOOS=linux  // 目标平台是linux
SET GOARCH=amd64  // 目标处理器架构是amd64

如果你的Windows使用的是PowerShell终端,那么设置环境变量的语法为

$ENV:CGO_ENABLED=0
$ENV:GOOS="linux"
$ENV:GOARCH="amd64"

7Linux编译Mac可执行文件

Linux平台下编译Mac平台64位可执行程序:

CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build

Linux编译Windows可执行文件

Linux平台下编译Windows平台64位可执行程序:

CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build

变量和常量

变量

变量的定义

var a int
var b bool 
var c int8var (m intn string
)var name string = "nazha"func main(){age := 18//声明变量age同时初始化;编译器会根据右边的初始值推断出age是什么类型
}

常量

const PI = 3.1415926const KB = 1024

iota

Go中借助iota来实现枚举

const (n1 = iota //0n2        //1n3        //2n4        //3)
  • iota在const关键字出现时将被重置为0

  • const中每新增一行常量声明将使iota累加一次

  • const声明的常量后面没有内容默认就跟上一行一致

    基本数据类型

String

使用双引号表示字符串 “hello”

使用单引号表示字符 ‘h’

字符串的常用方法

整型

int int8 int16 int32 int64

uint uint8 uint16 uint32 uint64

int是特殊的,会根据你的操作系统的位数来决定是int32还是int64

浮点型

float32 flot64

浮点数永远都是不精确.(为什么计算机表示的浮点数不精确)

  • 转换成字符串去做运算

  • 整体放大多少倍转换成整数进行运算

复数

complex64和complex128

布尔

var a bool//默认是false
var b = true

Go语言中布尔类型不能和其他类型做类型转换

byte和rune

英文字符用byte(ASCII码能表示的) 01010101

rune(中文,UTF8编码) 01010101 01010101 01010101

什么时候用rune?

s := "hello中国"
for i:=0;ifmt.
}

详见课上代码.

流程控制

if

age := 20
if age>18{}else if 20 > 18 {}else{}//此时age只在if语句中有效
if age:=20;age>18{}

for

//标准for循环
for i:=0;i<10;i++{}//类似while循环
n := 10
for n>0 {fmt.Println(n)n--
}//无限循环
for {}

switch和case

n := 10
switch n{case 1:...
case 2:...
}switch {case n>0:...case n ==0:...
}

为了兼容之前的C代码 fallthrough

以下是了解为主

goto+label

continue+label

break +label

作业

运算符

课后练习

把字符串的IP地址"192.168.19.200"转换成整数

格式化打印的参数

fmt.Println()
fmt.Printf("%s")

数组

数组是同一种数据类型元素的集合。

声明定义

初始化

二维数组

数组的遍历

数组是值类型

午后小分享

当你觉着不行的时候,你就去人行道上走一走,这个时候你就是一个行人。

切片

切片三要素:

  • 地址(切片中第一个元素指向的内存空间)
  • 大小(切片中目前元素的个数) len()
  • 容量(底层数组最大能存放的元素的个数) cap()

切片支持自动扩容,扩容策略3种

  • 每次只追加一个元素,每一次都是上一次的2倍

  • 追加的超过原来容量的1倍,就等于原来的容量+扩容元素个数的最接近的偶数

  • 如果切片的容量大于了1024,后续就每次扩容0.25倍 ?

给切片追加元素

append()函数是往切片中追加元素的。

a = append(a, 1)

得到切片的三种方式:

  • 直接声明a := []int{1,2,3} len:3 cap:3
  • 基于数组得到切片 m := [5]int b:= m[:3] len:3, cap:5
  • 基于切片得到切片 b := a[:2] len:2 cap:3

使用make初始化切片

make用于给引用类型申请内存空间

切片必须初始化,或者用append才能使用

var s []int
s = make([]int, 大小, 容量)

对切片初始化时,容量尽量大一点,减少程序运行期间再去动态扩容。

map

map定义

映射, key-value结构

var n map[string]int

map初始化

make(map[string]int, [容量])

map的遍历

for … range 循环

可变参数

func add4(a int, b ...int) int {}

可变参数只能有一个并且只能放在参数的最后!!!

Go语言中没有默认参数!!!

多返回值

func add5() (int, int, int) {return 1, 2, 3
}

变量和常量

变量

变量的定义

var a int
var b bool 
var c int8var (m intn string
)var name string = "nazha"func main(){age := 18//声明变量age同时初始化;编译器会根据右边的初始值推断出age是什么类型
}

常量

const PI = 3.1415926const KB = 1024

iota

Go中借助iota来实现枚举

const (n1 = iota //0n2        //1n3        //2n4        //3)
  • iota在const关键字出现时将被重置为0

  • const中每新增一行常量声明将使iota累加一次

  • const声明的常量后面没有内容默认就跟上一行一致

    基本数据类型

String

使用双引号表示字符串 “hello”

使用单引号表示字符 ‘h’

字符串的常用方法

整型

int int8 int16 int32 int64

uint uint8 uint16 uint32 uint64

int是特殊的,会根据你的操作系统的位数来决定是int32还是int64

浮点型

float32 flot64

浮点数永远都是不精确.(为什么计算机表示的浮点数不精确)

  • 转换成字符串去做运算

  • 整体放大多少倍转换成整数进行运算

复数

complex64和complex128

布尔

var a bool//默认是false
var b = true

Go语言中布尔类型不能和其他类型做类型转换

byte和rune

英文字符用byte(ASCII码能表示的) 01010101

rune(中文,UTF8编码) 01010101 01010101 01010101

什么时候用rune?

s := "hello中国"
for i:=0;ifmt.
}

详见课上代码.

流程控制

if

age := 20
if age>18{}else if 20 > 18 {}else{}//此时age只在if语句中有效
if age:=20;age>18{}

for

//标准for循环
for i:=0;i<10;i++{}//类似while循环
n := 10
for n>0 {fmt.Println(n)n--
}//无限循环
for {}

switch和case

n := 10
switch n{case 1:...
case 2:...
}switch {case n>0:...case n ==0:...
}

为了兼容之前的C代码 fallthrough

以下是了解为主

goto+label

continue+label

break +label

#################################################################

数组的定义

数组是带长度和元素类型!!!

var a [3]int
var b [3]string
var c [5]int

数组的初始化

var a = [3]int{1,2,3}
var b = [...]bool{true, false}
var c = [5]string{1:"娜扎", 3:"小王子"}

多维数组

var a = [3][2]int{{1, 2},{3, 4},{5, 6},
}

数组的遍历

  1. 根据索引index遍历
  2. for range遍历

切片

切片的定义

切片与数组的区别是没有固定的长度。

切片本质上就是一个数组。是语言层面对数组的封装。

切片是引用类型。

var a []int
var b []string
var c []bool

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xq27Jy9e-1678694805387)(D:\Go\src\code.oldboy.com\studygolang\day03\assets\1555208079167.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CtDnfXba-1678694805388)(D:\Go\src\code.oldboy.com\studygolang\day03\assets\1555208177025.png)]

Go语言中类型的初始值

值类型

var a int//0
var b string//
var c float32//0
var d [3]int//[0 0 0]
var e bool//false

引用类型 make()是给引用类型申请内存空间

var x []int//nil

切片的初始化

  1. 声明变量时初始化
  2. 数组切片得到
  3. 切片再切片得到
  4. make()函数创建

切片追加元素 append()

必须用变量接收append函数的返回值

切片的复制

copy(目标切片, 原切片)

切片删除元素

a = append(a[:1], a[2:]...)

map

map的定义

map是引用类型, 默认值是nil

map专门用来存储键值对类型的数据

判断某个键是否存在

v, ok := m[key]

函数

函数的定义

函数的参数

不带参数

多个相同类型的参数可以省略前面参数的类型

可变参数(...)

func f1(){fmt.Println("hello 沙河!")
}
//参数类型简写
func f2(name1, name2 string){fmt.Println(name1)fmt.Println(name2)
}
//可变参数 0个或多个
func f3(names ...string){fmt.Println(names)//[]string
}

函数的返回值

不带返回值

单个返回值

多个返回值

命名返回值

func f4(){fmt.Println("MJJ真烦")
}
func f5(a, b int) int{return a+b
}
//多返回值,必须用括号括起来,用英文逗号分隔
func f6(a, b int) (int, int){return a+b, a-b
}//命名的返回值
func f6(a, b int) (sum int, sub int){sum = a + bsub = a - breturn
}

匿名函数和闭包

变量的作用域

1. 全局作用域
2. 函数作用域
3. 语句块作用域

defer

defer延迟执行函数

defer先注册后执行(在函数即将要结束但还没有结束的时候执行)

多用来做一些资源回收类的工作。

指针

指针和地址有什么区别?

地址:就是内存地址(用字节来描述的内存地址)

指针:指针是带类型的。

&*

&:表示取地址

*:根据地址取值

new和make

new:是用来初始化值类型指针的

make:是用来初始化slicemapchan

	// 以下是错误的写法// var a *int //a是一个int类型的指针// var b *string// var c *[3]int// 以上是错误的写法var a = new(int) //得到一个int类型的指针fmt.Println(a)*a = 10fmt.Println(a)fmt.Println(*a)var c = new([3]int)fmt.Println(c)c[0] = 1fmt.Println(*c)

panic和recover

panic:运行时异常

recover:用来将函数在panic时恢复回来,用于做一些资源回收的操作

**注意:**程序会出现panic一定是不正常的。

结构体(struct)和方法

type关键字用来在Go语言中定义新的类型。

自定义类型和类型别名

自定义类型

创造一个新类型

type NewInt int

类型别名(软链)

var MyInt = int

byte: uint8 和 rune:int32是Go语言内置的别名。

类型别名只在代码编写过程中生效,编译完不存在。

结构体的定义

//结构体
// 创在新的类型要使用type关键字
type student struct {name   stringage    intgender stringhobby  []string
}func main() {var haojie = student{name:   "豪杰",age:    19,gender: "男",hobby:  []string{"篮球", "足球", "双色球"},}//结构体支持.访问属性fmt.Println(haojie)fmt.Println(haojie.name)fmt.Println(haojie.age)fmt.Println(haojie.gender)fmt.Println(haojie.hobby)
}

结构体的实例化

  1. 基本实例化

    var haojie = student{name:   "豪杰",age:    19,gender: "男",hobby:  []string{"篮球", "足球", "双色球"},}
    

结构体的初始化

结构体的内存布局

了解为主

结构体的字段在内存上是连续的。

func main() {type test struct {a int16b int16c int16}var t = test{a: 1,b: 2,c: 3,}fmt.Println(&(t.a))fmt.Println(&(t.b))fmt.Println(&(t.c))
}

构造函数

func newStudent(n string, age int, g string, h []string) *student {return &student{name:   n,age:    age,gender: g,hobby:  h,}

基于函数版学员信息管理系统

获取终端输入

fmt.Scan系列

需求分析

// 使用函数实现一个简单的图书管理系统。
// 每本书有书名、作者、价格、上架信息,
// 用户可以在控制台添加书籍、修改书籍信息、打印所有的书籍列表。// 0. 定义结构体
// 1. 打印菜单
// 2. 等待用户输入菜单选项
// 3. 添加书籍的函数
// 4. 修改书籍的函数
// 5. 展示书籍的函数
// 6. 退出 os.Exit(0)

接口

接口的定义

接口是一种类型,是一种抽象的类型。

是一个规范一个约定一堆方法签名的集合。

type mover interface {	move()
}

实现接口

实现了改接口规定的所有方法就实现了该接口

空接口

interface{}

任意变量都可以存到空接口变量中

指针接收者和值接收者实现接口的区别

文件操作

打开文件

os.Open()os.OpenFile()

time包

格式化的时间:2006-01-02 15:04:05.000

##############################################################

并发

并发和并行的区别

并发:同一时间段同时在做多个事情

并行:同一时刻同时在做多个事情

进程、线程、协程

进程:一个程序启动之后就创建了一个进程

线程:操作系统调度的最小单位

协程:用户态的线程(Python\PHP)

goroutine第六天

go运行时 runtime(Go语言作者帮我做的一些事情)

一个goroutine对应一个任务(函数)。

启动goroutine使用go关键字

sync.WaitGroup

Add(i):计数器+i

Done():计数器-1,最好用defer注册

Wait():等待

goroutine什么时候结束

一个goroutine对应一个任务(函数)。

函数结束了(return)goroutine就结束了

goroutine和线程的区别

m:n

将m个goroutine调度到n个线程上执行。

GOMAXPROCS

runtime.GOMAXPROCS(n)

channel

通道是引用类型,必须初始化才能使用。

ch1 := make(chan int, 10)

通道的基本操作

发送

接收

关闭

关闭的通道有哪些特点:

无缓冲通道和缓冲通道

无缓冲的通道:4*100交接棒,又称为同步通道

有缓冲的通道:可以让程序实现异步操作

取值时判断通道关闭

方法一: ok判断

// 利用for循环去通道ch1中接收值
for {ret, ok := <-ch1 // 使用 value, ok := <-ch1 取值方式,当通道关闭的时候 ok = falseif !ok {break}fmt.Println(ret)
}

方法二: for range 循环

// 利用for range 循环去通道ch1中接收值
for ret := range ch1 {fmt.Println(ret)
}

随机数

math/rand

	// 给rand加随机数种子实现每一次执行都能产生真正的随机数rand.Seed(time.Now().UnixNano())ret1 := rand.Int63() // int64正整数fmt.Println(ret1)ret2 := rand.Intn(101) // [1, 101)fmt.Println(ret2)

select

select {case ch1 <- 1:...case <- ch1:...case <- ch2:...}

单向通道

// chan *item :既能接收也能发送的一个队列
// chan<- *item :只能发送的一个队列(单向通道)
// <-chan *item :只能接收的一个队列(单向通道)

并发控制与锁

互斥锁

读写锁

只有在读的操作远远多于写的操作时使用读写锁才能提高性能。

sync.Once 和 sync.Map

########################################################

相关内容

热门资讯

信澳转型创新股票A净值下跌3.... 信澳转型创新股票型证券投资基金(简称:信澳转型创新股票A,代码001105)公布7月2日最新净值,下...
乌克兰日托米尔市一加油站附近发... 每经AI快讯,当地时间7月2日,乌克兰日托米尔州首府日托米尔市一加油站附近发生爆炸并引发大规模火灾,...
价格战遇红灯 车市“内卷”踩刹... 转自:天津日报  近日来,随着“零公里二手车”等话题持续引发市场讨论,汽车行业的“反内卷”声音一浪高...
长篇小说《太和》作品研讨会举办 转自:天津日报  本报讯(记者 仇宇浩)日前,天津市作家协会举办了尹学芸长篇小说《太和》作品研讨会。...
金种子酒管理层变动 营销改革力...   本报记者 梁傲男  7月2日,安徽金种子酒业股份有限公司(以下简称“金种子酒”)发布公告称,公司...
同泰大健康主题混合A净值下跌3... 同泰大健康主题混合型证券投资基金(简称:同泰大健康主题混合A,代码011002)公布7月2日最新净值...
金信精选成长混合C净值下跌3.... 金信精选成长混合型证券投资基金(简称:金信精选成长混合C,代码018777)公布7月2日最新净值,下...
原油:美越贸易协议推动油价在清...   受美国与越南达成贸易协议的消息推动,原油价格周三在公共假期前的清淡交投中走高。  WTI原油上涨...
万家经济新动能混合A净值下跌3... 万家经济新动能混合型证券投资基金(简称:万家经济新动能混合A,代码005311)公布7月2日最新净值...
中信建投医药健康C净值下跌3.... 中信建投医药健康混合型证券投资基金(简称:中信建投医药健康C,代码010091)公布7月2日最新净值...