当前位置:网站首页>go基础部分学习笔记记录
go基础部分学习笔记记录
2022-07-31 16:37:00 【Meme_xp】
函数和方法的区别
在Go语言中,函数和方法不太一样,有明确的概念区分。其他语言中,比如Java,一般来说函数就是方法,方法就是函数﹔但是在Go语言中,函数是指不属于任何结构体依类型的方法,也就是说函数是没有接收者的;而方法是有接收者的。
方法
func (t *T )add (a, b int) int {
return a + b
}
其中T是自定义奥型威者结构体。基础类型int等
函数
func add(a, b int) int {
return a + b
}
go方法值接收者和指针接收者的一个区别
结论:
如果方法的接收者是指针类型,无沦调用者是对象还是对象指针,修改的都是对象本身,会影响调用者;
如果方法的接收者是值类型,无论调用者是对象还是对象指针,修改的都是对象的副本,不影响调用者;
package main
import "fmt"
type Person struct {
age int
}
//如果实现了接收者是指针类型的方法,会隐含地也实现了接收者是值类型的IncrAge1方法。
//会修改age的值
func (p *Person) IncrAge1( ) {
p.age += 1
}
//如果实现了接收者是值类型的方法,会隐含地也实现了接收者是指针类型的IncrAge2方法。//不会修改age的值
func (p Person) IncrAge2( ) {
p.age += 1
}
//如果实现了接收者是值类型的方法,会隐含地也实现了接收者是指针类型的GetAge方法。
func (p Person) GetAge( ) int i{
return p.age
}
func main() {
//p是值类型
p := Person{
age: 10}
//值类型调用接收者是指针类型的方法
p.IncrAge1()
fmt.Println(p.GetAge( ))
//值类型调用接收者是值类型的方法
p.IncrAge2()
fmt.Println(p.GetAge( ))
//p2是指针类型
p2:=&Person{
age:20}
//指针类型,调用者的接收者是指针类型的方法
p2.IncrAge1()
fmt.Println(p2.GetAge( ))
//值类型调用接收者是值类型的方法
p2.IncrAge2()
fmt.Println(p2.GetAge( ))
通常我们使用指针类型作为方法的接收者的理由:
1.使用指针类型能修改调用者的值。
2.使用指针类型可以避免在每次调用方法时复制该值,在值的类型为大型结构体时,这样做会更加高效。
go函数返回局部变量后是不是安全的吗?
是安全的,但是会内存逃逸,分配在堆上面!!!
go函数参数传递是值传递还是值传递
Go语言中所有的传参都是值传递《传值),都是一个副本,一个拷贝。
参数如果是非引用类型(int、 string、struet等这些),这样就在函致中就无法修改原内容数据;如果是引用类型 指针、map、slice、chan等这些),这样就可以修改原内容数据。
是否可以修改原内容数据,和传值、传引用没有必然的关系。在C++中,传引用肯定是可以修改原内容数据的,在Go语言里,虽然只有传值,但是我们也可以修改原内容数据,因为参数是引用类型
传递slice也是值传递,但是传过去的是引用类型,因为slice的底层是这样的
直接传过去虽然可以修改切片的值,但是没法修改len和cap,只有传slice的地址才可以修改len和cap
map,chan本质也是一个指针,虽然是值传递,但是还是可以修改值
引用类型和引用传递是2个概念,切记!!!
defer的原理
定义:
defer能够让我们推迟执行某些函数调用,推迟到当前函数返回前才实际执行。defer与panic和recover结合,形成了Go语言风格的异常与捕获机制。
使用场景:
defer语句经常被用于处理成对的操作,如文件句柄关闭、连接关闭、释放锁
优点:
方便开发者使用
缺点:
有性能损耗
实现原理:
Go1.14中编译器会将deleri函数直接插入到函数的尾部,无需链表和栈上参数拷贝,性能大幅提升。把deler函数在当前函致内展开并直接调用,这种方式被称为open coded defer
注意:
2.panic后的defer函数不会被执行(遇到panic如果没有捕获到错误,函数会立即停止)
3. panic没有被recover时,抛出的panic到当前goroutine最上层函数时,最上层程序直接异常终止
package main
import "fmt"
func F() {
defer func(){
fmt.Println(""b")
}()
panic("a"")
}
//子函数抛出的panic没有recover时,上层函数时,程序直接异常终止
func main(){
defer func(){
fmt.Println(""c"")
}()
F()
fmt.Println("继续执行")
}
//b
//c
//panic: a
4. panic有被recover时,当前goroutine最上层函数正常执行
package main
import "fmt"
func F() {
defer func() {
if err := recover() ; err != nil {
fmt.Println("捕获异常: ",err)
}
fmt.Println(""b)
}()
panic("a")
}
func main(){
defer func(){
fmt.Println("c")
}()
F()
fmt.Println("继续执行")
}
//捕获异常: a
// b
//继续执行
// c
make和nwe函数
首先纠正下make和new是内置函数,不是关键字
变量初始化,一般包括2步,变量声明+变量内存分配,var关键字就是用来声明变量的, new和make函数主要是用来分配内存的
var声明值类型的变量时,系统会默认为他分配内存空间,并赋该类型的零值。比如布尔、数字、字符串、结构体。如果指针类型或者引用类型的变量,系统不会为它分配内存,默认就是ni1。此时如果你想直接使用,那么系统会抛异常,必须进行内存分配后,才能使用。
new和 make两个内置函数,主要用来分配内存空间,有了内存,变量就能使用了,主要有以下2点区别:
1.使用场景区别:
make只能用来分配及初始化类型为slice、map、chan的数据。
new可以分配任意类型的数据,并且置零。
2.返回值区别:
make函数原型如下,返回的是slice、map、chan类型本身
这3种类型是引用类型,就没有必要返回他们的指针
func make(t Type,size ...Integer Type)Type
new函数原型如下,返回一个指向该类型内存地址的指针
func new(Type)*Type
边栏推荐
- 最后写入胜利(丢弃并发写入)
- 牛客 HJ17 坐标移动
- flowable工作流所有业务概念
- T - sne + data visualization parts of the network parameters
- How to switch remote server in gerrit
- Smart Trash Can (8) - Infrared Tube Sensor (Raspberry Pi pico)
- 【Yugong Series】July 2022 Go Teaching Course 020-Array of Go Containers
- Graham's Scan method for solving convex hull problems
- Concurrency, Timing and Relativity
- 牛客 HJ16 购物单
猜你喜欢
go mode tidy出现报错go warning “all“ matched no packages
SringMVC中个常见的几个问题
【7.29】Code Source - 【Arrangement】【Stone Game II】【Cow and Snacks】【Minimum Number of Spawns】【Sequence】
智能垃圾桶(八)——红外对管传感器(树莓派pico)
i.MX6ULL驱动开发 | 33 - NXP原厂网络设备驱动浅读(LAN8720 PHY)
Smart Trash Can (8) - Infrared Tube Sensor (Raspberry Pi pico)
基于C语言的编译器设计与实现
Design and Implementation of Compiler Based on C Language
i.MX6ULL driver development | 33 - NXP original network device driver reading (LAN8720 PHY)
研发过程中的文档管理与工具
随机推荐
Premiere Pro 2022 for (pr 2022)v22.5.0
Flutter set the background color of the statusbar status bar and APP method (AppBar) internal consistent color.
The 2nd China PWA Developer Day
智能垃圾桶(九)——震动传感器(树莓派pico实现)
动态规划(一)
Qt practical cases (54) - using transparency QPixmap design pictures
adb shell error error: device unauthorized
你辛辛苦苦写的文章可能不是你的原创
SHELL内外置命令
form 表单提交后,使页面不跳转[通俗易懂]
Premiere Pro 2022 for (pr 2022)v22.5.0
i.MX6ULL driver development | 33 - NXP original network device driver reading (LAN8720 PHY)
你辛辛苦苦写的文章可能不是你的原创
第05章 存储引擎【1.MySQL架构篇】【MySQL高级】
Graham's Scan method for solving convex hull problems
【luogu P8326】Fliper(图论)(构造)(欧拉回路)
【C语言】LeetCode27.移除元素
Design and Implementation of Compiler Based on C Language
研发过程中的文档管理与工具
6-22 Vulnerability exploit - postgresql database password cracking