go语言 变量赋值

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" 最简洁,仅限函数内

:light_bulb: 建议:在函数内部优先使用短变量声明 :=,简洁高效;全局变量使用 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
}

对比总结

类型 定义位置 作用范围 是否支持 := 生命周期
全局变量 函数外部 整个包 :cross_mark: 不支持 程序运行期间
局部变量 函数内部 当前函数 :white_check_mark: 支持 函数执行期间
块级变量 代码块内 当前代码块 :white_check_mark: 支持 代码块执行期间

:warning: 注意:尽量减少全局变量的使用,过多的全局变量会增加代码耦合度,不利于维护。


定义多个变量

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 特点:

  • iotaconst 块中从 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语言有一套简洁的命名规范,遵循这些规范可以让代码更易读。

基本规则

  1. 只能包含:字母、数字、下划线 _
  2. 不能以数字开头
  3. 区分大小写nameName 是不同的变量
  4. 不能使用关键字:如 varfuncif

命名风格

类型 风格 示例
变量 小驼峰 userNameuserAge
常量 大驼峰或全大写 MaxSizeMAX_SIZE
函数 小驼峰(私有)/ 大驼峰(公开) getNameGetName
结构体 大驼峰 UserInfoOrderDetail

可见性规则(重要)

Go语言通过首字母大小写控制可见性:

var userName = "私有变量"  // 小写开头,仅包内可见
var UserName = "公开变量"  // 大写开头,包外可见

func getName() {}  // 私有函数
func GetName() {}  // 公开函数

命名建议

  • 变量名要有意义,避免使用 abx 等无意义名称
  • 短变量名适用于作用域小的场景,如循环变量 ij
  • 长变量名适用于作用域大的场景,如全局变量
  • 布尔类型建议用 ishascan 开头,如 isAdminhasPermission

输入输出

输出: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 分