Go_变量使用详解

变量

变量的本质是计算机分配的一块内存,用于存放数据,变量是在程序运行过程中,其值可以发生改变的数据,变量属于临时存储,当程序运行结束,存放该数据的内存就会释放,该变量就会随着内存的释放而消失。

局部变量&全局变量

  • 定义函数内部的变量称为局部变量,作用域在函数的内部。
  • 定义函数外部的变量称为全局变量,作用域是其它函数都可以使用。
  • 如果全局变量和局部变量的名字相同,在函数内使用时局部变量的优先级大于全局变量,采用就近原则。

变量名

  • 因为内存分配发生在运行期,所以在编码阶段我们用一个易于阅读的名字来表示这段内存,称为变量名。 而变量名只是为了让我们开发者更好的查找和使用,实际上编译后的机器码从不使用变量名,而是通过内存地址来访问目标数据。

  • 声明变量后就可以用=为它分配该类型的任何值

  • 变量名首字母大小写决定了其作用域,首字母大写相当于公开,可以被包外引用,而小写相当于私有,仅能在包内使用。(fmt.Println中的P是大写的,这样它就可以在任意包下被调用)

命名规则:

  • 优先选用有实际含义,易于阅读和理解的字母、单词或组合对变量、常量、函数、 自定义类型进行命名
  • 以字母或下划线开头,由字母、数字和下划线组成,且区分大小写(name、Name、NAME是三个变量)
  • 局部变量优先使用短命名(如下方代码所示)
	var c int                 // c代替count
	for i := 0; i < 10; i++ { // i代替index
		c++
	}

变量的定义

仅定义变量未初始化时,变量根据数据类型赋上默认值

整型、浮点型默认值 = 0
字符串默认值 = ""
布尔型默认值 = false
函数、指针变量、切片默认值 = nil

格式:

var 变量名 数据类型 // 仅定义,未赋值
var 变量名 数据类型 = 变量值 // 定义并赋值

演示:

func main() {
	var x int  		   // 定义x	没初始化	默认值0
	var y = 1  		   // 定义y	有初始化	数据类型int  将1赋值给y
	var z bool       // 定义z	没初始化	默认值为false
	var a int				 // 先定义a
	a = 1						 // 然后把1再赋值给a
	fmt.Println(x, y, z, a)
}

可以一次性定义多个变量

var 变量1,变量2 = 变量1,变量2

演示:

func main() {
	var x, y int               // 多个变量相同数据类型
	var n, m = 100, "itzhuzhu" // 多个变量不同数据类型
	fmt.Println(x, y, n, m)
}

多个变量以组的方式定义,不再需要每行都写var

func main() {
	var (
		x, y int               // 多个变量相同数据类型
		n, m = 100, "itzhuzhu" // 多个变量不同数据类型
	)
	fmt.Println(x, y, n, m)
}

变量存储:

  • 等号左边代表变量的内存空间(写)

  • 等号右边代表内存空间存储的数据值(读)

自动推导类型

在给变量赋值时,可以简化书写,使用:代替var由编译器根据赋值数据推断数据类型。

func main() {
	w := 1
	x, y, z := 2.3, 4, "itzhuzhu"
	fmt.Println(w, x, y, z)
  
  var intVal int 
 intVal =1 
}

拆分:=,:=做了两步的工作,所以声明的时候使用:=,再次赋值的时候使用=

	name := "娜可露露"

	// 相当于
	var name string
	name  = "娜可露露"

自动推导类型的弊端:

  • 定义变量同时要显式初始化,不能自定义数据类型
  • 自动推导类型创建的变量是局部变量,只能在同一个作用域下被调用
var x = 1            // 定义全局变量

func main() {
	fmt.Println(&x, x) // 全局变量

	var x = "局部变量" // 局部变量
	fmt.Println(&x, x)
}

输出:

0x10425c288 1
0x14000010070 局部变量

自动推导类型前提是至少有一个新声明的变量出现在左侧且在同一个作用域,即使其他变量名是重复的,编译器也不会报错

func main() {
	x := 1
	fmt.Println(&x)

	x, y := 2, "abc" // x在这里是重新赋值   y是定义新变量
	fmt.Println(&x, x, y)
}

打印结果:

0x14000096f60
0x14000096f60 2 abc

没有新的变量

func main() {
   x := 1
	fmt.Println(&x)

   x := 2 // 报错:':=' 的左侧没有新变量
	fmt.Println(&x, x)
}

有新的变量但不在同一个作用域将作为新变量定义

func main() {
	x := 1
	fmt.Println(&x)

	{
		x, y := 1, 2 // 这里的x和上面的x已经是不同作用域了,x,y全部视为定义新变量
	fmt.Println(&x, x, y)
	}
}

输出:

0x14000064f60
0x14000064f58 1 2

多变量赋值

在进行多变量赋值操作时,首先计算出所有右值,然后依次完成赋值操作,但必须保证左右值的数据类型相同

func main() {
	x, y := 1, 2    // x:1  y:2
	x, y = y+3, x+2 // 先计算出右值y+3、x+2,然后再把结果赋值给左边的x、y变量
	fmt.Println(y)
}

变量值交换:

func main() {
	var a = 1
	var b = 2
	var c int    // 定义第3个变量
	c = a				 // 把a的值给c
	a = b				 // 把b的值给a
	b = c				 // 把c的值给b
	fmt.Println(a, b)
}

// 也可以使用自动推导类型赋值的方式交换变量值
func main() {
	var a = 1
	var b = 2
	a, b = b, a
	fmt.Println(a, b)
}

忽略占位符/匿名变量

通常定义变量后未使用编译器就会报错,使用_可用来临时规避编译器对未使用变量和导入包的错误检查,匿名变量既不占用命名空间,也不会分配内存。

import (
	"fmt"
	_"os"	// 对于还没用到且不想删除的可以加上占位符,避免编译报错
)
	_, err = conn.Write([]byte(fileName))	// _:表示忽略占位符
	if err != nil {
		fmt.Println("conn.Write err:", err)
		return
}

你可能感兴趣的:(Golang,变量,常量,golang,Go语言)