Go 学习笔记(70)— Go 变量声明、变量初始化、值类型变量赋值、指针类型变量赋值

1. 变量声明

要单纯声明一个变量,可以通过 var 关键字,如下所示:

var s string

该示例只是声明了一个变量 s,类型为 string,并没有对它进行初始化,所以它的值为 string 的零值,也就是 “”(空字符串)。

来声明一个指针类型的变量试试,如下所示:

var sp *string

发现也是可以的,但是它同样没有被初始化,所以它的值是 *string 类型的零值,也就是 nil

2. 变量初始化

变量可以通过 = 运算符赋值,也就是修改变量的值。如果在声明一个变量的时候就给这个变量赋值,这种操作就称为变量的初始化。

如果要对一个变量初始化,可以有三种办法。

  1. 声明时直接初始化
var s string = "hello"
  1. 声明后再进行初始化
var s string
s = "hello"
  1. 使用 := 简单声明
s := "hello"

3. 不同类型变量赋值

3.1 值类型变量

func main() {
    
    
   var s string
   s = "hello"
   fmt.Println(s)
}

运行以上代码,可以正常打印,说明值类型的变量没有初始化时,直接赋值是没有问题的。

3.2 指针类型的变量呢

func main() {
    
    
   var sp *string
   *sp = "hello"
   fmt.Println(*sp)
}

运行这些代码,你会看到如下错误信息:

panic: runtime error: invalid memory address or nil pointer dereference

这是因为指针类型的变量如果没有分配内存,就默认是零值 nil,它没有指向的内存,所以无法使用,强行使用就会得到以上 nil 指针错误。

而对于值类型来说,即使只声明一个变量,没有对其初始化,该变量也会有分配好的内存。

在下面的示例中,声明了一个变量 s,并没有对其初始化,但是可以通过 &s 获取它的内存地址。这其实是 Go 语言帮我们做的,可以直接使用。

func main() {
    
    
   var s string
   fmt.Printf("%p\n",&s)
}

为什么 var wg sync.WaitGroup 声明的变量 wg 不进行初始化也可以直接使用?

因为 sync.WaitGroup 是一个 struct 结构体,是一个值类型,Go 语言自动分配了内存,所以可以直接使用,不会报 nil 异常。

总结: 如果要对一个变量赋值,这个变量必须有对应的分配好的内存,这样才可以对这块内存操作,完成赋值的目的。

注意:其实不止赋值操作,对于指针变量,如果没有分配内存,取值操作一样会报 nil 异常,因为没有可以操作的内存。

所以一个变量必须要经过声明、内存分配才能赋值,才可以在声明的时候进行初始化。指针类型在声明的时候,Go 语言并没有自动分配内存,所以不能对其进行赋值操作,这和值类型不一样。

所以 mapchan 也一样,因为它们本质上也是指针类型。

func main() {
    
    
	var d map[string]string
	d["aa"] = "123"
	fmt.Printf("%v\n", d)
}

报错:

panic: assignment to entry in nil map

猜你喜欢

转载自blog.csdn.net/wohu1104/article/details/111242722