变量定义与输入输出
2026年9月6日
这一课把两件事放在一起:怎么声明变量和常量,以及怎么用标准库 fmt 把值打出来、从终端读进去。
变量定义
标准的变量定义
var 可以先声明再赋值,也可以声明时一起写上初值:
package main
import "fmt"
func main() {
var name string
name = "槿"
var age int = 18
fmt.Println(name, age)
}
go
只声明、不赋值时,变量会落到该类型的零值:
string是"",int是0,bool是false,指针是nil。
变量类型省略
右边能推断出类型时,左边不必再写类型:
var name = "槿" // 推断为 string
var count = 3 // 推断为 int
go
简短声明
函数里更常见的是 :=,声明和赋值一步完成:
name := "槿"
count := 3
go
:= 只能用在函数内部。包级变量还是用 var。
左边至少要有一个新名字。已经存在的变量可以出现在左边,用来顺便重新赋值,但不能全是旧名字。
全局变量与局部变量
- 写在函数外面的是包级变量(常被叫作全局变量),可以声明后暂不使用。
- 写在函数里的是局部变量。Go 编译器要求声明了就必须用,否则过不了编译。
package main
import "fmt"
var site = "未使用也可以"
func main() {
name := "槿"
fmt.Println(name)
}
go
定义多个变量
同一类型可以写在一行;类型不同时,用类型推断或 :=:
var a, b, c string
var x, y = 1, "ok"
p, q := true, 3.14
go
一组相关的包级变量,用括号收拢更清楚:
var (
title string = "笔记"
author = "槿"
)
go
不需要的返回值用 _ 丢掉:
n, _ := fmt.Println("hello")
_ = n
go
常量定义
const 必须在定义时赋值,之后不能改:
const greeting = "hello"
// greeting = "hi" // 编译错误
go
一组整数常量可以用 iota 自增(从 0 起):
const (
StatusOK = iota
StatusFail
StatusSkip
)
go
命名规范
标识符以字母或 _ 开头,后面可以跟数字。习惯用驼峰。
首字母大写的名字可以在包外使用(导出);首字母小写只在本包可见。变量、函数、类型、结构体字段都按这个规则。
var Exported = 1 // 别的包能用
var hidden = 2 // 仅本包
go
输出
常用的输出函数
都在 fmt 里,默认写到标准输出:
| 函数 | 行为 |
|---|---|
Print | 原样拼接,不自动换行;相邻字符串中间没有空格 |
Println | 参数之间加空格,末尾加换行 |
Printf | 按格式化动词输出,换行要自己写 \n |
package main
import "fmt"
func main() {
fmt.Println("槿")
fmt.Println(1)
fmt.Println(true)
fmt.Println("可以", "一次", "打多个值")
}
go
写到别处(比如标准错误)用 Fprint / Fprintln / Fprintf,第一个参数换成 io.Writer。
格式化输出
Printf 用动词占位:
| 动词 | 含义 |
|---|---|
%v | 默认格式,多数情况先用这个 |
%T | 值的类型 |
%d | 十进制整数 |
%f / %.2f | 浮点 / 保留两位 |
%s | 字符串 |
%#v | 用 Go 语法打印,空字符串会显示成 "",调试很好用 |
%t | 布尔 |
%p | 指针 |
%% | 字面量 % |
package main
import "fmt"
func main() {
fmt.Printf("%v\n", "你好")
fmt.Printf("%v %T\n", "槿", "槿")
fmt.Printf("%d\n", 3)
fmt.Printf("%.2f\n", 1.25)
fmt.Printf("%s\n", "ok")
fmt.Printf("%#v\n", "")
}
go
要把格式化结果收进变量,用 Sprintf,它返回字符串、不打印:
msg := fmt.Sprintf("%s,今年 %d", "槿", 18)
fmt.Println(msg)
go
输入
Scan / Scanln / Scanf 从标准输入读,结果写进指针:
package main
import "fmt"
func main() {
fmt.Print("输入名字: ")
var name string
fmt.Scan(&name)
fmt.Println("你输入的是", name)
}
go
&name 是取地址。指针后面会单独讲,这里先记住:扫描函数要的是变量地址,不是变量本身。
| 函数 | 行为 |
|---|---|
Scan | 按空白(空格、换行、Tab)拆开读 |
Scanln | 读到换行就停 |
Scanf | 按格式串读,例如 "%s %d" |
它们都返回「成功读到几个值」和 error。输入对不上类型时要检查 err,否则变量可能还是零值。
Scan 会在第一个空格处切开,不适合读「一行里带空格的句子」。那种情况用 bufio.Scanner 按行读。