Go学习第3天:变量+常量+运算符

Go 语言变量、常量、运算符)

一、Go 变量

变量用于存储数据,可读写、运行过程中值可修改。Go 是静态强类型语言,变量必须先声明再使用。

1.1 变量命名规则

说明

  1. 字母、数字、下划线 _ 组成;
  2. 首字符不能是数字
  3. 不能使用 Go 关键字作为变量名;
  4. 区分大小写;
  5. 见名知意,推荐驼峰命名。

合法/非法示例

  • 合法:name_ageuserIDnum123
  • 非法:123abc(数字开头)、a+b(含特殊符号)、case(关键字)

1.2 变量声明四大方式

方式1:标准声明(var + 变量名 + 类型)

语法
go 复制代码
var 变量名 数据类型
说明

只声明、不初始化,变量会自动赋予零值

零值规则(重点)
  • 数值类型(int/float):0
  • 布尔类型:false
  • 字符串:""(空字符串)
  • 指针、切片、map、channel、函数、error:nil
示例
go 复制代码
package main
import "fmt"

func main() {
    var a int
    var b float64
    var c bool
    var d string

    fmt.Printf("a=%d, b=%f, c=%t, d=%q\n", a, b, c, d)
}
运行结果
复制代码
a=0, b=0.000000, c=false, d=""
踩坑

只声明不赋值的局部变量必须使用 ,否则编译报错 declared but not used;全局变量允许声明不使用。


方式2:声明并初始化(var + 变量名 + 类型 + 值)

语法
go 复制代码
var 变量名 类型 = 值
示例
go 复制代码
package main
import "fmt"

func main() {
    var name string = "张三"
    var age int = 20
    fmt.Println(name, age)
}

方式3:类型推断(省略类型,编译器自动识别)

语法
go 复制代码
var 变量名 = 值
说明

根据右侧值自动推导变量类型,日常使用频率很高。

示例
go 复制代码
package main
import "fmt"

func main() {
    var str = "Go语言"
    var num = 100
    fmt.Println(str, num)
}

方式4:短变量声明(:=,最常用)

语法
go 复制代码
变量名 := 值
说明
  1. 等价于 var 变量名 类型 = 值
  2. 只能在函数内部使用,不能声明全局变量;
  3. 必须同时声明+赋值,不能只声明不赋值。
示例
go 复制代码
package main
import "fmt"

func main() {
    msg := "短变量声明"
    fmt.Println(msg)
}
踩坑(高频错误)
  1. 同一作用域不能重复用 := 声明同名变量

    go 复制代码
    func main() {
        a := 10
        a := 20 // 报错:no new variables on left side of :=
    }

    修正:直接赋值 a = 20

  2. := 不能用于全局变量

    go 复制代码
    msg := "全局变量" // 语法报错

    修正:全局变量使用 var 声明。


1.3 多变量声明

1. 同行声明多个同类型变量

go 复制代码
var v1, v2, v3 类型
var v1, v2, v3 类型 = 值1, 值2, 值3

示例:

go 复制代码
var a, b int = 1, 2
fmt.Println(a, b)

2. 同行声明多个不同类型变量(类型推断)

go 复制代码
var v1, v2 = 值1, 值2

示例:

go 复制代码
var name, age = "李四", 22
fmt.Println(name, age)

3. 因式分解写法(推荐全局变量)

批量声明多个不同类型全局变量,代码整洁。

语法
go 复制代码
var (
    变量1 类型 = 值1
    变量2 类型 = 值2
    变量3 = 值3
)
示例
go 复制代码
package main
import "fmt"

// 全局变量组
var (
    id   int    = 1
    addr string = "北京"
    flag        = true
)

func main() {
    fmt.Println(id, addr, flag)
}

4. 短变量多变量声明(函数内)

go 复制代码
v1, v2 := 值1, 值2

示例:

go 复制代码
func main() {
    x, y := 10, "test"
    fmt.Println(x, y)
}

1.4 变量作用域

  1. 局部变量:函数/代码块内声明,仅当前代码块有效,函数执行完毕自动销毁。
  2. 全局变量 :函数外声明,整个包内有效;首字母大写可跨包访问。
  3. 变量重名 :局部变量和全局变量可以同名,局部变量优先(就近原则)。
示例
go 复制代码
package main
import "fmt"

// 全局变量
var num int = 100

func main() {
    // 局部变量,覆盖全局
    var num int = 200
    fmt.Println(num) // 输出 200
}

1.5 空白标识符 _

说明

_只写变量 ,用于丢弃不需要的返回值,解决 Go 变量必须被使用的规则。

语法

go 复制代码
_, 变量 = 返回值1, 返回值2

示例

go 复制代码
package main
import "fmt"

// 函数返回两个值
func calc() (int, int) {
    return 10, 20
}

func main() {
    // 丢弃第一个返回值,只接收第二个
    _, b := calc()
    fmt.Println(b) // 20
}
踩坑

不能读取 _ 的值,fmt.Println(_) 直接编译报错。


1.6 值类型 & 引用类型

1. 值类型

  • 包含:int、float、bool、string、数组
  • 特点:赋值时完整拷贝数据,新旧变量互不影响;变量存储在栈内存。

示例

go 复制代码
a := 10
b := a
b = 20
fmt.Println(a) // 10,a 不受影响

2. 引用类型

  • 包含:切片、map、指针、channel、函数
  • 特点:赋值时只拷贝内存地址,多个变量指向同一份数据;修改一个,全部受影响。

二、Go 常量

常量是程序运行期间值固定不可修改 的量,使用 const 声明。

2.1 常量基础语法

说明

  1. 常量只能修饰:布尔、数值、字符串类型;
  2. 声明时必须赋值,无零值概念;
  3. 不能使用 := 声明常量。

基础语法

go 复制代码
// 显式指定类型
const 常量名 类型 = 值

// 类型推断(省略类型,推荐)
const 常量名 = 值

示例

go 复制代码
package main
import "fmt"

func main() {
    const PI float64 = 3.14159
    const NAME = "Go学习"

    fmt.Println(PI, NAME)
}
踩坑

常量声明后禁止修改,如下代码直接编译报错:

go 复制代码
const a = 10
a = 20 // 报错:cannot assign to a

2.2 多常量声明

1. 同行多常量

go 复制代码
const c1, c2 = 值1, 值2

2. 因式分解批量常量(常用,枚举场景)

go 复制代码
const (
    常量1 = 值1
    常量2 = 值2
    常量3 = 值3
)

示例(简单枚举):

go 复制代码
const (
    UNKNOWN = 0
    MALE    = 1
    FEMALE  = 2
)

2.3 常量与内置函数

常量表达式中可以使用 Go 内置函数lencapunsafe.Sizeof),普通自定义函数不支持。

示例

go 复制代码
package main
import (
    "fmt"
    "unsafe"
)

const (
    str = "hello"
    l   = len(str)
    s   = unsafe.Sizeof(str)
)

func main() {
    fmt.Println(str, l, s)
}

2.4 特殊常量:iota(枚举计数器)

核心规则

  1. iota常量组专用计数器
  2. const 关键字出现时,iota 重置为 0
  3. 常量组内每新增一行iota 自动 +1;
  4. 上一行常量无赋值时,默认继承上一行表达式。

用法1:基础自增

go 复制代码
package main
import "fmt"

const (
    a = iota // 0
    b        // 1(继承 a = iota)
    c        // 2
)

func main() {
    fmt.Println(a, b, c) // 0 1 2
}

用法2:穿插自定义值,打断自增

go 复制代码
const (
    a = iota // 0
    b        // 1
    d = "ha" // 自定义值,iota+1 → 2
    e        // "ha",iota+1 → 3
    f = 100  // 自定义值,iota+1 → 4
    g        // 100,iota+1 → 5
    h = iota // 5
)

用法3:位运算结合 iota(经典场景)

go 复制代码
package main
import "fmt"

const (
    i = 1 << iota // 1 << 0 = 1
    j = 3 << iota // 3 << 1 = 6
    k             // 3 << 2 = 12
    l             // 3 << 3 = 24
)

func main() {
    fmt.Println(i, j, k, l) // 1 6 12 24
}
踩坑
  1. iota 仅在 const 常量组内生效,单独使用无效;
  2. 普通变量不能使用 iota

三、Go 运算符

运算符用于数据运算、逻辑判断,分为:算术、关系、逻辑、位、赋值、其他运算符,同时包含优先级规则。

3.1 算术运算符

适用于数值类型,共 7 个。

运算符 作用 示例(A=10,B=20)
+ 相加 A+B = 30
- 相减 A-B = -10
* 相乘 A*B = 200
/ 整除 B/A = 2
% 取余 B%A = 0
++ 自增 A++ → 11
-- 自减 A-- → 9

完整示例

go 复制代码
package main
import "fmt"

func main() {
    var a = 21
    var b = 10
    fmt.Println(a + b)
    fmt.Println(a - b)
    fmt.Println(a * b)
    fmt.Println(a / b)
    fmt.Println(a % b)

    a++
    fmt.Println(a)
    a--
    fmt.Println(a)
}

高频踩坑

  1. 整数相除结果为整数 ,小数部分直接舍弃:5 / 2 = 2

  2. 自增/自减只能单独使用 ,不能参与赋值运算:

    go 复制代码
    a := 10
    b := a++ // 编译报错,Go 不支持
  3. 取余 % 不能用于浮点类型

3.2 关系运算符(比较运算符)

返回结果为 bool 类型(true/false),常用于 if/for 判断。

运算符 作用
== 相等
!= 不相等
> 大于
< 小于
>= 大于等于
<= 小于等于

示例

go 复制代码
package main
import "fmt"

func main() {
    a := 21
    b := 10
    if a == b {
        fmt.Println("相等")
    } else {
        fmt.Println("不相等")
    }
    fmt.Println(a > b)
}
踩坑

判断相等是 ==,不要写成赋值 =

3.3 逻辑运算符

多用于多条件组合判断,操作数和结果均为布尔值。

运算符 名称 规则
&& 逻辑与 两边都为 true,结果才为 true(短路:左边 false 直接终止)
` `
! 逻辑非 取反,true → false,false → true

示例

go 复制代码
package main
import "fmt"

func main() {
    a := true
    b := false

    fmt.Println(a && b) // false
    fmt.Println(a || b) // true
    fmt.Println(!a)     // false
}

3.4 位运算符

对整数二进制位 进行操作,底层开发、权限掩码常用。

假定:a=60(0011 1100)b=13(0000 1101)

运算符 作用 结果
& 按位与 对应位都为1才为1 → 12
` ` 按位或
^ 按位异或 对应位不同则为1 → 49
<< 左移 n 位 整体左移,低位补0 → a<<2 = 240
>> 右移 n 位 整体右移,高位补0 → a>>2 = 15

示例

go 复制代码
package main
import "fmt"

func main() {
    var a uint = 60
    var b uint = 13
    fmt.Println(a & b)
    fmt.Println(a | b)
    fmt.Println(a ^ b)
    fmt.Println(a << 2)
    fmt.Println(a >> 2)
}

3.5 赋值运算符

结合运算 + 赋值,简化代码写法。

运算符 等价写法
= 基础赋值
+= a = a + b
-= a = a - b
*= a = a * b
/= a = a / b
%= a = a % b
<<= 左移后赋值
>>= 右移后赋值
&= 按位与后赋值
` =`
^= 按位异或后赋值

示例

go 复制代码
package main
import "fmt"

func main() {
    a := 10
    a += 5  // a = 10 +5
    fmt.Println(a)
    a *= 2
    fmt.Println(a)
}

3.6 其他运算符(地址 & 指针)

运算符 作用
& 取变量内存地址
* 解引用,取指针指向的值

示例

go 复制代码
package main
import "fmt"

func main() {
    a := 4
    var ptr *int // 定义指针变量

    ptr = &a     // 取 a 的地址赋值给指针
    fmt.Println("a 的地址:", ptr)
    fmt.Println("a 的值:", *ptr) // 通过指针取值
}

3.7 运算符优先级

优先级由高到低 ,同优先级从左向右运算;括号 () 优先级最高,可手动改变运算顺序。

  1. * / % << >> & &^
  2. + - | ^
  3. == != < <= > >=
  4. &&
  5. ||

示例(括号改变优先级)

go 复制代码
package main
import "fmt"

func main() {
    a, b, c, d := 20, 10, 15, 5
    e := (a + b) * c / d
    fmt.Println(e)
}

相关推荐
专注搞钱17 小时前
用Python写了个SPC自动分析工具,效率提升10倍
开发语言·python
码云骑士17 小时前
【3.Java基础】Java运算符详解:从算数运算到逻辑判断,一篇文章全部掌握
java·开发语言
sensen_kiss17 小时前
CPT304 SoftwareEngineeringII 软件工程 2 Pt.6 批判性分析 / 关键性分析(Critical Analysis)
学习·软件工程
雪落漂泊17 小时前
C++ 继承与多态(下)
开发语言·c++
写代码的白开水17 小时前
从 RAG 到 LLM Wiki:团队知识库工程化的一点学习
学习
川冰ICE17 小时前
JavaScript工程化②|Webpack5基础配置,打包你的第一个项目
开发语言·javascript·ecmascript
YHHLAI17 小时前
JavaScript 同步异步精讲:单线程、事件循环、Promise 执行机制
开发语言·javascript·ecmascript
yijianace17 小时前
Python爬虫实战:ThreadPoolExecutor多线程采集书籍信息与图片下载
开发语言·爬虫·python
资深流水灯工程师17 小时前
PySide6 + Qt Designer + PyCharm 完整开发流程
开发语言·qt·pycharm