最新Go语言语法总结_go语法总结(2),2024年最新作为一个Golang程序员

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

defer close(myChan) // 一般在项目中, 创建管道后, 再 defer 关闭
// 写入值
myChan <- 1
// 关闭通道后, 不可再往管道写入值
close(myChan)
myChan <- 2 // panic: send on closed channel

#### 结构体


若干种类型字段的集合, 它是一整块内存空间


###### 1. 定义结构体


* 定义struct
* 面向对象特性: 封装
* 初始化



// struct
type animal struct {
id int
name string
age int
}

// 先声明
var dog animal
// 再赋值
dog.id = 1
dog.name = “bai”
dog.age = 2

// 声明并赋值
cat := animal{
id: 2,
name: “hei”,
age: 1,
}

// new, 返回指针地址
pig := new(animal)
pig.id = 3
pig.name = “hui”
pig.age = 5

fmt.Println(dog, cat, pig) // {1 bai 2} {2 hei 1} &{3 hui 5}


###### 2. 属性及方法定义


* 作用域, 首字母大写表示公共的, 包外可调用, 首字母小写表示私有的, 包内可见, 包外无法调用



type animal struct {
// 结构体属性
id int
name string
age int
}

func (a *animal) run() {
fmt.Println(“running…”, a.name)
}

// new
dog := new(animal)

dog.id = 1
dog.name = “la”
dog.age = 2
// 调用方法
dog.run() // running… la


###### 3. 组合


* 面向对象特性: 继承
* 组合实现 ( 结构体嵌套 )



type biology struct {
birthday time.Time
}

type animal struct {
// 结构体属性
id int
name string
age int
// 结构体嵌套
biology
}

func (a *animal) run() {
fmt.Println(“running…”, a.name)
}

func (b *biology) birth() {
fmt.Println(“today is my birthday”)
}

// new
dog := new(animal)

dog.id = 1
dog.name = “la”
dog.age = 2
dog.birthday = time.Now().Local()
// 调用方法
dog.run() // running… la
// 可以直接使用嵌套结构体的方法
dog.birth() // today is my birthday


#### 接口


接口可以这样理解, 公共方法组合起来, 以封装特定功能的一个集合, 抽象出接口的目的就是让一些类去实现它, 接口本质上是指针类型


* 面向对象特性: 多态 ( 接口的多种不同实现方式 )
* 接口定义变量



// 定义接口, 实现接口中所有的方法, 即实现了这个接口
type behavior interface {
speak() string
move()
}

type person struct {
name string
}

type dog struct {
name string
}

// 隐性实现接口
func (p *person) speak() string {
return “hello”
}

func (p *person) move() {
fmt.Println(p.name, " move…")
}

// 隐性实现接口
func (d *dog) speak() string {
return “~~~”
}

func (d *dog) move() {
fmt.Println(d.name, " move…")
}

// 接口类型作为函数参数
func do(b behavior) {
fmt.Println(b.speak())
b.move()
}

// 实现了接口的结构体对象, 就可以存储在接口变量中
var i behavior

long := new(person) // new, 返回指针类型
long.name = “long”

// 赋值给接口变量
i = long
i.move()

dog := new(dog)
dog.name = “dog”

i = dog
fmt.Println(i.speak())

// 实现了接口的结构体, 就可以作为函数do的参数
do(long)
do(dog)


#### 并发


* 并发实现: 协程 ( 用户态维护, 比线程更小, 需要的内存也更少, 比线程更易用, 而且更高效更轻量 )
* 通过管道实现多协程间的通信
* 通过锁机制实现多协程间的同步


###### 1. 协程


* 启动协程
* 多核CPU设置



// 获取当前主机CPU逻辑核心数
CPUNum := runtime.NumCPU()

// 设置启动的最大CPU个数
runtime.GOMAXPROCS(CPUNum - 1)

// 利用go关键字开启goroutine, 并行
go func() {
for i := 0; i < 10; i++ {
fmt.Println(i)
}
}()

// 此时如果不加睡眠时间, 终端任何打印结果都没有, 因为主函数为主goroutine, 启动其他子goroutine时, 还没来得及打印结果输出, 主函数程序就执行完了, 即主goroutine结束后, 子goroutine也会一起结束退出
time.Sleep(time.Second * 1)


###### 2. 协程通信


* 管道 channel 在协程之间接收和发送数据, 进行数据交互
* 多管道之间通过 select 调度, select 一般与 for 配置使用



myChan := make(chan int, 5)
overChan := make(chan bool, 1)

go func() {
// 发送数据到管道
for i := 0; i < 5; i++ {
myChan <- i
time.Sleep(1 * time.Second)
}
overChan <- true
}()

go func() {
// 循环从管道中取值
for {
// select 监听多个管道
select {
case num := <-myChan:
fmt.Println(num)
case <-overChan:
fmt.Println(“over”)
break
}
}
}()

time.Sleep(10 * time.Second)


###### 3. 协程同步


系统工具 sync.WaitGroup


* Add(delta int) 添加协程记录
* Done() 移除协程记录
* Wait() 同步等待所有记录的协程全部结束



var wg sync.WaitGroup

for i := 0; i < 5; i++ {
// 添加记录
wg.Add(1)
go func() {
// 移除记录
defer wg.Done()
fmt.Println(“hello”)
time.Sleep(time.Second * 1)
}()
}

// 等待
wg.Wait()


#### 指针


###### 1. 基本使用


* 定义指针变量
* 为指针变量赋值
* 访问指针变量中指向地址的值



// 定义一个int类型的指针变量, 未赋值为nil, 不支持指针运算
var ptr *int

num := 1
// 取指针地址, 即变量num的内存地址
ptr = &num
// 根据指针地址, 取其指向的值
myNum := *ptr

fmt.Println(ptr, myNum) // 0xc00000a2e0 1


###### 2. 指针数组与数组指针



// 定义指针数组
var pointArr [2]*int
age, money := 20, 100

pointArr[0] = &age
pointArr[1] = &money

fmt.Println(pointArr) // [0xc00000a2e0 0xc00000a2e8]

// 数组指针
var ptr *[2]int

myArr := [2]int{1, 2}

ptr = &myArr

fmt.Println(ptr) // &[1 2]


#### JSON


###### 1. 序列化


* 结构体序列化及 Tag
* Map 序列化



// 序列化, Tag标签类似于别名, 它既可以满足字段被包外使用, 又可以对外提供指定的别名
type user struct {
Name string json:"name"
Age int json:"age"
Admin bool json:"admin"
}

u := user{
Name: “long”,
Age: 20,
Admin: true,
}

// 结构体序列化时, 注意结构体的字段首字母一定要大写, 否则json包无法获取, 小写为本包内私有
bytes, err := json.Marshal(&u)
if err != nil {
fmt.Println("error: ", err)
return
}

fmt.Println(string(bytes)) // {“Name”:“long”,“Age”:20,“Admin”:true}, 加入 Tag 后 {“name”:“long”,“age”:20,“admin”:true}



// 只声明, 默认为nil
var user map[string]string
// 需要开辟内存空间后, 才能赋值, 或者直接声明并初始化 user := make(map[string]string)
user = make(map[string]string)

user[“name”] = “long”
user[“addr”] = “hangzhou”
user[“age”] = “20”

// 序列化
bytes, err := json.Marshal(user)
if err != nil {
fmt.Println("error: ", err)
return
}

fmt.Println(string(bytes)) // {“addr”:“hangzhou”,“age”:“20”,“name”:“long”}


###### 2. 反序列化


* 反序列化为结构体
* 反序列化为 Map



// 反序列化
type user struct {
Name string json:"name"
Age int json:"age"
Admin bool json:"admin"
}

str := {"name":"chao","age":18,"admin":false}

var u user

// 反序列化时, 应该传入结构体指针, 因为要修改值并且结构体字段首字母大写 (包外可见)
err := json.Unmarshal([]byte(str), &u) // 它会根据 Tag 找对应的结构体字段, 然后赋值
if err != nil {
fmt.Println("error: ", err)
return
}

fmt.Println(u) // {chao 18 false}

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

// 它会根据 Tag 找对应的结构体字段, 然后赋值
if err != nil {
fmt.Println("error: ", err)
return
}

fmt.Println(u) // {chao 18 false}

[外链图片转存中…(img-IaYPkqp7-1715571725712)]
[外链图片转存中…(img-RadRR06U-1715571725713)]
[外链图片转存中…(img-KZXWRbmu-1715571725713)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 16
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值