Go语言变量定义与输入输出
概述
Go语言中变量定义有多种方式,灵活且简洁。本文介绍Go语言中变量定义、常量定义、命名规范以及输入输出的基本用法。
一、先声明再赋值
var name string
name = "Littlemole"
fmt.Println(name)
说明:
- 使用
var关键字声明变量,并指定类型 - 声明后再单独赋值
- 适用于需要先声明、后续再赋值的场景
二、声明的同时赋值
var age string = "Littlemole is 18 years old"
fmt.Println(age)
说明:
- 使用
var关键字声明变量,同时指定类型和初始值 - 写法完整,类型明确
- 适用于需要明确指定类型的场景
三、类型自动推导
var address = "Littlemole lives in Beijing"
fmt.Println(address)
说明:
- 使用
var关键字声明变量,省略类型 - 编译器根据赋值内容自动推导变量类型
- 代码更简洁,适用于类型明显的场景
四、短变量声明(推荐)
gender := "Littlemole is male"
fmt.Println(gender)
说明:
- 使用
:=操作符,省略var关键字 - 自动推导变量类型
- 只能在函数体内使用,不能用于全局变量
- 最简洁的写法,Go语言中最常用
完整示例
package main
import "fmt"
func HelloWorld() {
fmt.Println("Hello, World!")
gender := "Littlemole is male"
fmt.Println(gender)
// 省略var,自动推导变量类型(只能在函数体内使用)
}
func main() {
var name string
name = "Littlemole"
fmt.Println(name)
// 先声明再赋值
var age string = "Littlemole is 18 years old"
fmt.Println(age)
// 声明的同时赋值
var address = "Littlemole lives in Beijing"
fmt.Println(address)
// 根据值自动推导变量类型
HelloWorld()
}
总结
| 方式 | 语法 | 特点 |
|---|---|---|
| 先声明再赋值 | var name string |
类型明确,分步操作 |
| 声明同时赋值 | var age string = "value" |
完整写法,类型明确 |
| 类型自动推导 | var address = "value" |
省略类型,自动推导 |
| 短变量声明 | name := "value" |
最简洁,仅限函数内 |
建议:在函数内部优先使用短变量声明
:=,简洁高效;全局变量使用var声明。
全局变量与局部变量
全局变量
定义在函数外部的变量,整个包内都可以访问。
package main
import "fmt"
// 全局变量
var globalName string = "我是全局变量"
var globalAge = 18
func main() {
fmt.Println(globalName) // 可以访问
fmt.Println(globalAge) // 可以访问
test()
}
func test() {
fmt.Println(globalName) // 其他函数也可以访问
}
特点:
- 定义在函数外部
- 整个包内的所有函数都可以访问
- 不能使用
:=短变量声明,必须使用var - 生命周期:程序运行期间一直存在
局部变量
定义在函数内部的变量,只能在该函数内访问。
package main
import "fmt"
func main() {
// 局部变量
localName := "我是局部变量"
fmt.Println(localName) // 可以访问
}
func test() {
// fmt.Println(localName) // 报错!无法访问其他函数的局部变量
}
特点:
- 定义在函数内部
- 只能在定义它的函数内访问
- 可以使用
:=短变量声明 - 生命周期:函数执行时创建,函数结束时销毁
块级作用域
局部变量还可以进一步限制在代码块内(如 if、for 内部)。
func main() {
if true {
blockVar := "我只在if块内有效"
fmt.Println(blockVar) // 可以访问
}
// fmt.Println(blockVar) // 报错!超出作用域
}
变量覆盖(就近原则)
当局部变量和全局变量同名时,局部变量会覆盖全局变量。
package main
import "fmt"
var name = "全局的name"
func main() {
name := "局部的name" // 覆盖全局变量
fmt.Println(name) // 输出:局部的name
}
对比总结
| 类型 | 定义位置 | 作用范围 | 是否支持 := |
生命周期 |
|---|---|---|---|---|
| 全局变量 | 函数外部 | 整个包 | 程序运行期间 | |
| 局部变量 | 函数内部 | 当前函数 | 函数执行期间 | |
| 块级变量 | 代码块内 | 当前代码块 | 代码块执行期间 |
注意:尽量减少全局变量的使用,过多的全局变量会增加代码耦合度,不利于维护。
定义多个变量
Go语言支持同时定义多个变量,有以下几种方式:
方式一:逐个定义
var a string = "hello"
var b int = 10
var c bool = true
方式二:批量定义(推荐)
使用 var() 语法块,一次性定义多个变量:
var (
name string = "Littlemole"
age int = 18
gender string = "male"
)
方式三:同类型多变量
同一类型的多个变量可以写在一行:
var a, b, c int = 1, 2, 3
方式四:短变量批量声明
函数内部可以使用 := 同时声明多个变量:
func main() {
name, age, gender := "Littlemole", 18, "male"
fmt.Println(name, age, gender)
}
常量定义
常量是程序运行期间不可改变的值,使用 const 关键字定义。
基本定义
const PI float64 = 3.14159
const APP_NAME = "MyApp" // 类型自动推导
批量定义
const (
STATUS_OK = 200
STATUS_ERROR = 500
APP_VERSION = "1.0.0"
)
iota 枚举
iota 是Go语言的常量计数器,只能在常量表达式中使用。
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
iota 特点:
iota在const块中从 0 开始- 每新增一行常量声明,
iota自动加 1 - 遇到新的
const块会重置为 0
iota 高级用法
const (
_ = iota // 0,使用 _ 忽略
KB = 1 << (10 * iota) // 1 << 10 = 1024
MB // 1 << 20 = 1048576
GB // 1 << 30
TB // 1 << 40
)
命名规范
Go语言有一套简洁的命名规范,遵循这些规范可以让代码更易读。
基本规则
- 只能包含:字母、数字、下划线
_ - 不能以数字开头
- 区分大小写:
name和Name是不同的变量 - 不能使用关键字:如
var、func、if等
命名风格
| 类型 | 风格 | 示例 |
|---|---|---|
| 变量 | 小驼峰 | userName、userAge |
| 常量 | 大驼峰或全大写 | MaxSize、MAX_SIZE |
| 函数 | 小驼峰(私有)/ 大驼峰(公开) | getName、GetName |
| 结构体 | 大驼峰 | UserInfo、OrderDetail |
可见性规则(重要)
Go语言通过首字母大小写控制可见性:
var userName = "私有变量" // 小写开头,仅包内可见
var UserName = "公开变量" // 大写开头,包外可见
func getName() {} // 私有函数
func GetName() {} // 公开函数
命名建议
- 变量名要有意义,避免使用
a、b、x等无意义名称 - 短变量名适用于作用域小的场景,如循环变量
i、j - 长变量名适用于作用域大的场景,如全局变量
- 布尔类型建议用
is、has、can开头,如isAdmin、hasPermission
输入输出
输出:fmt.Print 系列
Go语言使用 fmt 包进行输入输出操作。
fmt.Print
直接输出,不换行:
fmt.Print("Hello")
fmt.Print("World")
// 输出:HelloWorld
fmt.Println
输出后自动换行:
fmt.Println("Hello")
fmt.Println("World")
// 输出:
// Hello
// World
fmt.Printf
格式化输出,支持占位符:
name := "Littlemole"
age := 18
fmt.Printf("姓名:%s\n", name)
fmt.Printf("年龄:%d\n", age)
fmt.Printf("姓名:%s,年龄:%d\n", name, age)
常用格式化占位符
| 占位符 | 说明 | 示例 |
|---|---|---|
%s |
字符串 | fmt.Printf("%s", "hello") |
%d |
整数 | fmt.Printf("%d", 18) |
%f |
浮点数 | fmt.Printf("%f", 3.14) |
%.2f |
保留2位小数 | fmt.Printf("%.2f", 3.14159) → 3.14 |
%t |
布尔值 | fmt.Printf("%t", true) |
%v |
自动推断类型 | fmt.Printf("%v", anything) |
%+v |
输出结构体带字段名 | fmt.Printf("%+v", user) |
%T |
输出变量类型 | fmt.Printf("%T", name) → string |
%p |
指针地址 | fmt.Printf("%p", &name) |
%% |
输出百分号 | fmt.Printf("100%%") → 100% |
输入:fmt.Scan 系列
fmt.Scan
从标准输入读取数据,以空格或换行分隔:
var name string
var age int
fmt.Print("请输入姓名和年龄:")
fmt.Scan(&name, &age) // 注意要用 & 取地址
fmt.Printf("姓名:%s,年龄:%d\n", name, age)
fmt.Scanln
读取一行输入,遇到换行符结束:
var name string
fmt.Print("请输入姓名:")
fmt.Scanln(&name)
fmt.Scanf
按指定格式读取输入:
var name string
var age int
fmt.Print("请输入(格式:姓名-年龄):")
fmt.Scanf("%s-%d", &name, &age)
完整输入输出示例
package main
import "fmt"
func main() {
var name string
var age int
var score float64
fmt.Print("请输入姓名:")
fmt.Scanln(&name)
fmt.Print("请输入年龄:")
fmt.Scanln(&age)
fmt.Print("请输入成绩:")
fmt.Scanln(&score)
fmt.Println("========== 信息汇总 ==========")
fmt.Printf("姓名:%s\n", name)
fmt.Printf("年龄:%d 岁\n", age)
fmt.Printf("成绩:%.2f 分\n", score)
}
运行效果:
请输入姓名:Littlemole
请输入年龄:18
请输入成绩:95.5
========== 信息汇总 ==========
姓名:Littlemole
年龄:18 岁
成绩:95.50 分