Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go声明变量与常量

Go语言中声明变量(var)与常量(const)的完整指南

作者:妙莎

本文介绍了Go语言中变量和常量的定义方式,包括标准声明、类型推断、声明赋值、短变量声明、多变量声明等,以及常量的定义方式、导出规则、命名规则等,同时,还讲解了标识符的语法规则、作用域和遮蔽的概念

序言:今天开始学习 Go 语言的 变量与常量,该文章会记录一些相关的知识点和案例。

变量

定义

用于存储程序运行时可改变的数据

声明方式

方式语法适用场景示例
标准声明var 变量名 类型 = 表达式显式指定类型 或 需要零值初始化var age int = 25
类型推断var 变量名 = 表达式省略类型,由右侧值推导var age = 25
声明赋值var 变量名 类型
变量名 = 表达式
省略类型,由右侧值推导先声明,后赋值var age int
age = 25
短变量声明变量名 := 表达式函数内部,最常用、最简洁age := 25
多变量声明var (变量1 类型1 = 值1 ...)
var 变量1,变量2 = 值1,值2 )
批量声明,常用于包级别var (age int = 25; name string = "windy")
var a, b = 1,2

示例:标准声明

package main

import "fmt"

func main() {
	var age int = 25
	fmt.Println(age)
}

输出:25

这种声明方式虽然很清晰明了,但对我来说有点麻烦。代码敲多了的时候,是不会考虑这种,因为有点累脑费眼,所以优先于简洁的方式。

示例:类型推断

package main

import "fmt"

func main() {
	var age = 25
	fmt.Println(age)
}

输出:25

这种声明方式相对于第一个来说简单了些,我一般用于全局变量(看情况进行初始化),例如存储验证码。

示例:声明赋值

package main

import "fmt"

func main() {
    var age int
    age = 25
    fmt.Println(age)
}

输出:25

这种声明方式乍一看比第一个还复杂,但我用的比较多,例如初始化结构体,然后根据需求挨个进行赋值。

示例:短变量声明

package main

import "fmt"

func main() {
    age := 25
    fmt.Println(age)
}

输出:25 

这种声明方式最简洁,我用的也多,例如调用函数的时接收结果( res, _ := myFun() )。

示例:多变量声明

import "fmt"

func main() {
    var (
       age  int    = 25
       name string = "windy"
    )
    fmt.Println(age, name)
    
    var a, b = 1, 2
    fmt.Println(a, b)
}
// 也可以删除类型,结果是一样的

输出:

25 windy
12

 这种声明方式我基本上就是了解了解,就没用过。

短变量声明的一些小细节

示例:重复声明规则

运行成功

package main

import "fmt"

func myFunOne() (string, error) {
	return "Hello", nil
}

func myFunTwo() (string, error) {
	return "world", nil
}

func main() {
	one, err := myFunOne() // 声明 a 和 err
	two, err := myFunTwo() // 声明 b,对 err 赋值(合法,因为 b 是新的)
	fmt.Println(one, two, err)
}

输出:Hello world <nil>

没编译时就提示报错

package main

import "fmt"

func myFunOne() (string, error) {
    return "Hello", nil
}

func myFunTwo() (string, error) {
    return "world", nil
}

func main() {
    one, err := myFunOne() // 声明 a 和 err
    one, err := myFunTwo()  // 报错,左侧无新变量
    fmt.Println(one, err)
}
// 报错提示:No new variables on the left side of ':=', Replace with'='
// 左边没有新变量,直接用 = 即可(会覆盖之前的值)

特殊的空白标识符

Go 的短变量声明 := 中,下划线 _ 是一个特殊的空白标识符。它用于占位,表示主动忽略某个返回值或声明项。关于它的使用,有几个关键点需要特别注意:

_ 不算“新变量”,不参与重复声明规则的判定

_ 无法被读取,只用于占位丢弃值

 _ 声明的变量 “未使用” 不会报错:Go 编译器强制要求声明的非 _ 变量必须被使用。但 _ 是唯一的例外,它可以被多次 “声明” 且永不使用。

_ 不能用于常量或类型声明:_ 仅在 变量声明 和 赋值 场景作为占位符,不能用于 const 或 type 定义。

在 := 中左侧全是 _ 是语法错误

记住:把 _ 当成黑洞,它只为满足语法结构而存在,不参与任何变量计数的逻辑。

常量

定义

编译时确定、运行时不改变的值

声明方式

方式语法示例
标准声明const 常量名 类型 = 表达式const Age int = 25
类型推断const 常量名 = 表达式const Age = 25
多常量声明const (常量1 类型1 = 值1 ...)const (Age int = 25; Name string = "windy")
隐式重复多常量声明块中省略右值时自动沿用上一行表达式const ( A = 1; B; C )

示例:标准声明

package main

import "fmt"

func main() {
    const age int = 25
    fmt.Println(age)
}

 输出:25

这种声明方式虽然有点麻烦,但很清晰明了。一般来说,常量定义的数量比变量少很多,且大多数都定义在函数外,调用常量的时候能一下子知道是什么类型的会比较好。

示例:类型推断

package main

import "fmt"

func main() {
    const age = 25
    fmt.Println(age)
}

输出:25

这种声明方式个人习惯上不常使用,推荐第一种。

示例:多常量声明

package main

import "fmt"

func main() {
    const (
       age  int    = 25
       name string = "windy"
    )
    fmt.Println(age, name)
}
// 也可以删除类型,结果是一样的

输出:25 windy

这种声明方式一般在定义差不多含义的常量的时候使用,比如返回码( 200,404,500 等 )。

示例:隐式重复

package main

import "fmt"

func main() {
    const (
       Apple  = "fruit"
       Banana // = "fruit"
       Cherry // = "fruit"
    )
    // Banana 和 Cherry 的值都是 "fruit"
    fmt.Println(Apple, Banana, Cherry)
}

输出: fruit fruit fruit

基本上没用过这种声明方式,不知道以后会不会有用得到的场景

命名规则

标识符语法规则(强制)

导出规则(可见性控制)

Go 没有 public/private 关键字,而是用 首字母的大小写 控制包外可见性:

首字母可见性术语
大写包外可访问Exported (导出标识符)
小写下划线仅包内可访问Unexported (未导出标识符)

命名风格约定(非强制,但强烈推荐)

Go 社区遵循一套统一的命名风格,保证了代码的可读性和一致性:

对象类型风格示例
变量驼峰式 (camelCase)userCounthttpRequest
常量驼峰式 (PascalCasecamelCase)MaxRetries (导出), defaultPort (未导出)
函数 / 方法驼峰式GetUserparseData
类型名驼峰式,首字母大写(导出)UserServicehttpClient (未导出)
包名全小写,简短,无下划线timehttputilstrings
接口名通常以 er 结尾(单方法接口)ReaderWriterCloser
缩写词全大写或全小写,保持一致HTTPServer (或 httpServer),不能写成 HttpServer

特殊命名约定 与 注意点

使用范围(作用域 Scope)

作用域决定了标识符( 变量名、常量名 )在代码中的可见范围。Go 的作用域是词法作用域静态作用域),由代码块 {} 界定。

作用域层级(从大到小)

级别声明位置可见范围
全局作用域所有函数之外整个包(package)内
包级私有函数外,首字母小写仅当前包
包级导出函数外,首字母大写当前包 + 其他导入此包的包
函数作用域函数体内任何位置该函数体内(从声明点到函数结束)
块作用域ifforswitch 的 {} 内仅该花括号块内

作用域遮蔽 (Shadowing)

内层作用域声明的变量若与外层同名,会 遮蔽 外层变量。这是 Go 代码中非常常见的

示例

package main

import "fmt"

var myName = "true" // 包级变量

func main() {
    fmt.Println(myName) // 输出 true

    // 在块内声明同名变量,创建了新变量而非修改外层
    if true {
       var myName = "false"
       fmt.Println(myName)
       // 这个 myName 是块内新变量,值为 false
    }
    fmt.Println(myName) // 仍然输出 true,包级变量未被修改
}

输出:

true
false
true

为了节省脑子,尽量不重名,如果实在不想思考其他切合的名字,就直接 name1name2

避免遮蔽的建议

包级变量 与 常量 的初始化顺序

以上就是Go语言中声明变量(var)与常量(const)的完整指南的详细内容,更多关于Go声明变量与常量的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文