基本语法
声明
全局变量 | 局部变量 | |
---|---|---|
声明语法 | <font style="color:rgb(0, 0, 136);">var</font><font style="color:rgb(0, 0, 0);"> var_name </font><font style="color:rgb(102, 102, 0);">*</font><font style="color:rgb(0, 0, 136);">var</font><font style="color:rgb(102, 102, 0);">-</font><font style="color:rgb(0, 0, 0);">type</font> 比如:<font style="color:rgb(0, 0, 0);">var ip *int</font> |
1. 声明和右边相同 2. 短运算符 b := &a |
:::info 指针类型有哪些?
:::
Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:int、int64、*string等。初始化
Go语言中的指针操作非常简单,只需要记住两个互补操作符:&(取地址)和*(根据地址取值)。- 取地址:
ptr := &v
// v的类型为T- v和T都是代号
v:代表被取地址的变量,类型为T
ptr:用于接收地址的变量,ptr的类型就为T,称做T的指针类型。代表指针。
- 取值:
prt = &a; b := *prt
- 初始化要求
初始化必须给地址/指针而不能是值——指针不能声明**<font style="color:rgb(51, 51, 51);">var</font>** a ***<font style="color:rgb(51, 51, 51);">int</font>**
之后就*a = 100
(所以我们有了new和make两个内置函数,请见后文) - 空指针——默认初始化为nil
与c语言不同的是,无须专门赋值指针为空指针,golang中只要没别分配到任何变量时候,默认为nil
与c语言的不同
- 语法上
- c语言:
int* prt;
类型是int*
- go语言:
var prt *int
类型是*int
——看*
的位置,非常不同
- c语言:
- 默认值为nil,没有NULL常量,c语言赋予NULL之后可
- 不支持指针与整数的算术运算,不支持
->
运算符,直接用.
访问目标成员地址
调用
向函数传递指针
和c相同,略
!new和make
看个例子:
执行上面的代码会引发panic,为什么呢?——值类型和引用类型的声明作用不同 1. 对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储。
func main() {
var a *int
*a = 100//错在这
fmt.Println(*a)
var b map[string]int
b["测试"] = 100//这也错了
fmt.Println(b)
}
➡只有初始化和new/make内建函数才能为其分配内存 2. 而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间。
可以什么? | 不可以什么? | |
---|---|---|
var a *int | a = b(b是另一个已经初始化的变量) =让遥控器指向新电视 |
a = 100 why? 给我小米遥控器,但还没给我电视,所以无法往里导入节目 + 小米 = int + 遥控器 = 指针 + 电视 = 分配内存 + 导入节目 = 赋值 |
a = new(int) | + a = b + *a = 100 给了未激活的电视,只有默认栏目,可以导入节目,也可以让遥控器指向另一个电视 |
new
函数签名:func **<font style="color:rgb(51, 51, 51);">new</font>**(Type) *Type
其中:
- 接受:一个类型Type
- 返回:这个类型的指针 *Type
作用:
new函数不太常用,使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值。(特别注意:这里和默认初始化的nil,也就是空指针,还是有区别)我们使用new函数,无需担心其内存的生命周期或者怎样将其删除,因为GO语言的内存管理系统会帮我们打理一切 实例:go
func main() {
a := new(int)
b := new(bool)
fmt.Printf("%T\n", a) // *int
fmt.Printf("%T\n", b) // *bool
fmt.Println(*a) // 0
fmt.Println(*b) // false
}
我们要是用new函数来改造上上的例子
go
func main() {
var a *int
a = new(int)
*a = 10//这就行了
fmt.Println(*a)
}
#### make
:::info
作用
:::
make也是用于内存分配的,区别于new,它只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。
:::info
make函数的函数签名如下::::
**<font style="color:rgb(51, 51, 51);">func</font>** **<font style="color:rgb(51, 51, 51);">make</font>**(**<font style="color:rgb(51, 51, 51);">t</font>** **<font style="color:rgb(51, 51, 51);">Type</font>**, **<font style="color:rgb(51, 51, 51);">size</font>** ...IntegerType) **<font style="color:rgb(51, 51, 51);">Type</font>**
区别
- 二者都是用来做内存分配的。
- make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身;
- 而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。