Go 里面的变量

127 阅读5分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。

什么是变量

在数学概念中,变量表示没有固定值且可改变的数。但从计算机系统实现角度来看

  • 变量是为存储特定类型的值而提供给内存位置的名称
  • 在go中声明变量有多种语法
  • 所以变量的本质就是一小块内存,用于存储数据,在程序运行过程中数值可以改变

Go语言的基本类型有:

  • bool
  • string
  • int、int8、int16、int32、int64
  • uint、uint8、uint16、uint32、uint64、uintptr
  • byte // uint8 的别名
  • rune // int32 的别名 代表一个 Unicode 码
  • float32、float64
  • complex64、complex128

声明变量

声明规则

var名称类型是声明单个变量的语法。

以字母或下划线开头,由一个或多个字母、数字、下划线组成

变量的命名规则遵循骆驼命名法,即首个单词小写,每个新单词的首字母大写,例如:numShips 和 startDate 。

变量的声明有几种形式,通过下面几节进行整理归纳。

声明方式一

  • 定变量类型,通用的变量声明形式
  • 声明后若不赋值,使用零值(默认值)
  • var name type

其中,var 是声明变量的关键字,name 是变量名,type 是变量的类型。

var strs string
strs = "小菠萝测试笔记" 

需要注意的是,Go语言和许多编程语言不同,它在声明变量时将变量的类型放在变量的名称之后。这样做的好处就是可以避免像C语言中那样含糊不清的声明形式,例如:int* a, b; 。其中只有 a 是指针而 b 不是。如果你想要这两个变量都是指针,则需要将它们分开书写。而在 Go 中,则可以和轻松地将它们都声明为指针类型:

var a, b *int

声明方式二

  • 语法糖形式
  • 根据值自行判定变量类型(类型推断Type inference),相当于自定义默认值
  • 这是一种省略类型信息声明的【语法糖】
  • 仅适用于在变量声明的同时显式赋予变量初值的情况
var nums = 123

声明方式三

  • 语法糖形式
  • 简短声明(短变量声明),省略var,类似 Python 中的海象赋值,:=
c := 20

这种方式它只能被用在函数体内,而不可以用于全局变量的声明与赋值


注意

  • := 左侧的变量不应该是已经声明过的
  • 但是多个变量同时声明时,左侧可以出现已经声明过的变量,前提是至少保证有一个新变量,否则会导致编译错误
a := 1
a, b, c := 2, 3, 4

重新赋值的 a 变量,赋值类型应该保持和首次声明时的类型一致

有且只有这种方式可以给同个变量多次声明

多变量声明

方式一

以逗号分隔,声明与赋值分开,若不赋值,则取默认值

var name1, name2, name3 string

name1, name2, name3 = "1", "b", "str"

方式二

直接赋值,不同变量可以赋值不同类型的值

var v1, v2, v3, v4 = 1, 1.1, true, "test"

方式三

变量声明块

var (
    n1 string
    n2 bool
    n3 int
)

方式四

简短声明

a1,a2, a3 := 1, 2, 3

注意事项

  • 变量必须先定义才能使用
  • go语言是静态语言,要求变量的类型和赋值的类型必须一致
  • 变量名不能冲突(同一个作用域内不能冲突)
  • 简短定义方式声明多个变量时,左边的变量名至少有一个是新的
  • 简短定义方式,不能定义全局变量
  • 变量的零值,也叫默认值
  • 变量定义了就要使用,否则无法通过编译

零值(默认值)

  • 数值类型为 0,
  • 布尔类型为 false,
  • 字符串为 ""(空字符串)
  • 指针为nil

变量名不能冲突(同一个作用域内不能冲突)

var a int
// 这是赋值,不冲突
a = 2

// 这是声明,所以冲突了
a := 2

// 这样就不冲突了,因为左侧有新的变量名
a, b := 1, 2

变量必须使用

  • 在同一个作用域中,已存在同名的变量,则之后的声明初始化,则退化为赋值操作
  • 但这个前提是,最少要有一个新的变量被定义,且在同一作用域
package main

import (
    "fmt"
)

func main() {
    x := 140
    fmt.Println(&x)
    x, y := 200, "abc"
    fmt.Println(&x, x)
    fmt.Print(y)
}

运行结果

0xc00001c0d8
0xc00001c0d8 200
abc

Go 包级变量和局部变量会根据具体情况选择不同的变量声明形式

匿名变量

匿名变量是一个下划线“”。“”本身就是一个特殊的标识符,被称为空白标识符。它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用,也不可以使用这个标识符作为变量对其它变量进行赋值或运算。使用匿名变量时,只需要在变量声明的地方使用下划线替换即可

举个栗子

package main

import "fmt"

func GetData() (int, int) {
	return 100, 200
}

func main(){
	a, _ := GetData()
	_, b := GetData()
	fmt.Println(a, b)
}

运行一下

在以上代码中:

  • 第10行只需要获取第一个返回值,所以将第二个返回值的变量设为匿名变量
  • 第11行将第一个返回值的变量设为匿名变量