Skip to content

Go 变量

变量 (Variable) 是内存中一个命名的存储位置,用于存储一个值。程序使用变量来存储和操作数据。

Go 中的每个变量都有一个特定的 类型 (type),它决定了:

变量名(标识符)遵循基本语法章节中概述的规则(以字母或下划线开头,后跟字母、数字、下划线;区分大小写)。

Go 提供了丰富的内置类型。以下是一些基本类型:

类型 (Type)描述 (Description)示例值 (Example Values)
bool布尔值 (Boolean value)true, false
string字节序列(通常表示 UTF-8 编码的文本)"Hello, Go!", ""
int有符号整数(大小取决于平台:32 位或 64 位)-10, 0, 123
int8, int16, int32, int64具有特定位大小的有符号整数-128 到 127 (int8) 等
uint无符号整数(大小取决于平台:32 位或 64 位)0, 42, 1000
uint8, uint16, uint32, uint64具有特定位大小的无符号整数0 到 255 (uint8) 等
byteuint8 的别名 (Alias)'a', 0x41
runeint32 的别名。表示一个 Unicode 码点。'✓', '世'
float32, float64浮点数 (IEEE-754 标准)。通常首选 float64。3.14, -0.5, 1.0e6
complex64, complex128复数(实部和虚部分别为 float32 或 float64)complex(2, -3)

Go 还提供了更复杂的类型,如数组 (arrays)、切片 (slices)、映射 (maps)、结构体 (structs)、指针 (pointers)、通道 (channels)、接口 (interfaces) 和函数 (functions),这些将在后续章节中介绍。

声明变量会告诉编译器为它预留内存。Go 提供了几种声明变量的方式:

  1. 使用 var 和类型进行声明(零值初始化):

这种形式声明一个或多个指定类型的变量。如果没有提供初始值,变量将被初始化为其 零值 (zero value)(例如,数字类型为 0,bool 为 false,string 为 "",指针、切片、映射等为 nil)。

var count int // 声明一个 int 类型的变量 'count',初始化为 0
var message string // 声明一个 string 类型的变量 'message',初始化为 ""
var isActive bool // 声明一个 bool 类型的变量 'isActive',初始化为 false
var i, j, k int // 声明多个 int 类型的变量,都初始化为 0
  1. 使用 var、类型和初始值进行声明:

这种形式声明一个变量并显式地分配一个初始值。

var score int = 100
var name string = "Alice"
var pi float64 = 3.14159
  1. 使用 var 和初始值进行声明(类型推断 Type Inference):

如果提供了初始值,Go 通常可以推断出类型,因此可以省略类型声明。

var age = 30 // 类型被推断为 int
var greeting = "Hi there" // 类型被推断为 string
var enabled = true // 类型被推断为 bool
// 声明多个变量并进行类型推断
var a, b, c = 1, 2.5, "xyz"
  1. 短变量声明符 (:=)(类型推断):

在函数内部,可以使用 := 短变量声明 (short assignment statement)。它声明变量并使用类型推断进行初始化。这是 Go 中在函数内部声明变量最常用的方式。

注意: 短变量声明 (:=) 只能在函数内部使用,不能在包级别 (package level) 使用。在包级别,必须使用 var。

func main() {
count := 10 // 类型被推断为 int
message := "Success" // 类型被推断为 string
isValid := false // 类型被推断为 bool
x, y := 5, "five" // 声明多个变量
}

何时使用 var vs :=:

package main
import "fmt"
// 包级别变量 (必须使用 var)
var globalMessage = "This is global"
func main() {
// 使用 var 零值初始化
var counter int
fmt.Printf("Initial counter: %d (Type: %T)\n", counter, counter)
// 使用 var 显式指定类型和值
var price float64 = 99.95
fmt.Printf("Price: %.2f (Type: %T)\n", price, price)
// 使用 var 类型推断
var quantity = 5
fmt.Printf("Quantity: %d (Type: %T)\n", quantity, quantity)
// 使用短变量声明符 (:=)
productName := "Widget"
fmt.Printf("Product: %s (Type: %T)\n", productName, productName)
// 混合声明并进行类型推断
a, b, c := true, 10.5, "Mixed"
fmt.Printf("a: %t (%T), b: %.1f (%T), c: %s (%T)\n", a, a, b, b, c, c)
fmt.Println(globalMessage)
}

编译并执行后,输出如下:

Initial counter: 0 (Type: int)
Price: 99.95 (Type: float64)
Quantity: 5 (Type: int)
Product: Widget (Type: string)
a: true (bool), b: 10.5 (float64), c: Mixed (string)
This is global

可赋值性 (Assignability)(左值 Lvalues 和右值 Rvalues)

Section titled “可赋值性 (Assignability)(左值 Lvalues 和右值 Rvalues)”

在赋值操作符 (=, :=) 中,左侧必须引用一个可以存储值的内存位置(有时称为 左值 或更简单的,一个可赋值的操作数)。右侧必须产生一个值(有时称为 右值)。

变量是可赋值的:

count = 10 // 有效:'count' 引用一个内存位置

字面量 (Literals)(例如数字或字符串)是值,而不是内存位置,因此不能放在赋值操作符的左侧:

100 = count // 无效:不能赋值给字面值 100