变量定义
局部变量
先来看看几种标准的变量定义方式(以string为例)
go
package main
import "fmt"
// 以string为例
func main() {
// 先定义,再赋值
var name string
name = "Y_Yao"
fmt.Println(name) //Y_Yao
// 定义时赋值
var name1 string = "Y_Yao"
fmt.Println(name1) //Y_Yao
// 变量类型可以省略,让编译器自己推导
var name2 = "Y_Yao"
fmt.Println(name2) //Y_Yao
// 简短声明,可以省略var关键字
name3 := "Y_Yao"
fmt.Println(name3) //Y_Yao
// 定义了但没有赋值,为零值
var name4 string
fmt.Println(name4) //空字符串,啥也不输出
}
全局变量
全局变量可以只定义不使用,局部变量定义了就必须使用,不然编译报错。
go
package main
var name string = "Y_Yao"
var name1 = "Y_Yao"
name2 := "Y_Yao" //错误写法,全局变量必须使用var关键字
func main() {
}
注意:全局变量不能使用简短声明,必须使用var关键字
定义多个变量
go
package main
import "fmt"
func main() {
// 定义多个变量
var a1, a2, a3 string
fmt.Println(a1, a2, a3) // 没赋值时为0值,啥也不显示
// 定义多个变量并赋值
var name1, name2, name3 = "Y_Yao", "hello", "world"
fmt.Println(name1, name2, name3) // Y_Yao hello world
//简短定义多个变量并赋值
b1, b2, b3 := "Y_Yao", "hello", "world"
fmt.Println(b1, b2, b3) // Y_Yao hello world
//var () 定义多个变量并赋值
var (
//可以省略类型
c1 string = "Y_Yao"
c2 = "hello"
c3 = "world"
)
fmt.Println(c1, c2, c3) // Y_Yao hello world
}
常量定义
go
package main
import "fmt"
// 定义时就要赋值,可以省略类型,以后无法修改
const name string = "Y_Yao"
const name1 = "Y_Yao"
func main() {
fmt.Println(name, name1) // Y_Yao Y_Yao
}
命令规范
核心思想:首字母大写的变量、函数。方法,属性可在包外进行访问
go中什么是包?
在 Go 项目中,一个目录 就对应一个包 。同一个目录下的所有 .go文件必须归属于同一个包 。目录的路径(相对于 go.mod文件的位置)决定了这个包的导入路径。
如下图,我新建一个test包,其实就是在项目中新建了一个test目录:

然后在原来的main.go中就可以引用里面的包,访问符合命名规范的变量
go
package main
import (
"CommandSpe/test" // 引入自定义包
"fmt"
)
func main() {
fmt.Println(test.Name) // 符合命名规范,首字母大写
fmt.Println(test.name) // 错误写法,name不符合命名规范,无法访问,编译报错
}
输出
常用的输出函数
go
package main
import "fmt"
func main() {
// Println 可以理解成Printline的缩写,打印一行的意思,也就是说打印完,他会自动打印一个换行符
fmt.Println("Hello World")
fmt.Println(1)
// Hello World
// 1
// Print 只简单打印,不会自己加换行符
fmt.Print("Hello World")
fmt.Print("1")
// Hello World1
}
格式化输出
go
package main
import "fmt"
func main() {
// 通用格式
fmt.Printf("默认格式: %v\n", "你好") // 默认格式: 你好
fmt.Printf("Go语法表示: %#v\n", "你好") // Go语法表示: "你好"
fmt.Printf("类型: %T\n", "你好") // 类型: string
// 整数格式
fmt.Printf("十进制: %d\n", 42) // 十进制: 42
fmt.Printf("二进制: %b\n", 5) // 二进制: 101
fmt.Printf("十六进制: 0x%X\n", 255) // 十六进制: 0xFF
// 浮点数格式
fmt.Printf("保留两位小数: %.2f\n", 3.14159) // 保留两位小数: 3.14
fmt.Printf("科学计数法: %e\n", 1000.0) // 科学计数法: 1.000000e+03
// 字符串格式
fmt.Printf("原样输出: %s\n", "Hello") // 原样输出: Hello
fmt.Printf("带引号: %q\n", "Hello") // 带引号: "Hello"
// 宽度与对齐
fmt.Printf("右对齐: |%5d|\n", 12) // 右对齐: | 12|
fmt.Printf("左对齐: |%-5d|\n", 12) // 左对齐: |12 |
fmt.Printf("补零: %05d\n", 12) // 补零: 00012
}
格式化动词
里面的格式化动词我汇总如下:
| 类别 | 动词 | 描述 | 示例 |
|---|---|---|---|
| 通用格式 | %v |
值的默认格式 | Printf("%v", obj) |
%+v |
类似%v,但结构体添加字段名 |
Printf("%+v", struct{Name string}{"你好"})→ {Name:你好} |
|
%#v |
值的Go语法表示 | Printf("%#v", "你好")→ "你好" |
|
%T |
值的类型 | Printf("%T", 42)→ int |
|
%% |
字面百分号 | Printf("完成度 50%%")→ 完成度 50% |
|
| 布尔型 | %t |
布尔值(true/false) | Printf("%t", true)→ true |
| 整数 | %b |
二进制 | Printf("%b", 5)→ 101 |
%c |
Unicode码点对应的字符 | Printf("%c", 65)→ A |
|
%d |
十进制(最常用) | Printf("%d", 42)→ 42 |
|
%o |
八进制 | Printf("%o", 8)→ 10 |
|
%O |
带前缀0o的八进制 | Printf("%O", 8)→ 0o10 |
|
%x |
十六进制(小写a-f) | Printf("%x", 255)→ ff |
|
%X |
十六进制(大写A-F) | Printf("%X", 255)→ FF |
|
%U |
Unicode格式:U+1234 | Printf("%U", 'A')→ U+0041 |
|
%q |
单引号括起来的字符字面值 | Printf("%q", 65)→ 'A' |
|
| 浮点数 | %f/ %F |
有小数点而无指数 | Printf("%.2f", 3.14159)→ 3.14 |
%e |
科学计数法(e小写) | Printf("%e", 1000.0)→ 1.000000e+03 |
|
%E |
科学计数法(E大写) | Printf("%E", 1000.0)→ 1.000000E+03 |
|
%g |
紧凑格式(根据需要选%e或%f) |
Printf("%g", 1000.0)→ 1000 |
|
%G |
紧凑格式(根据需要选%E或%F) |
Printf("%G", 1000000.0)→ 1E+06 |
|
| 复数 | 同浮点数 | 输出为(实数+虚数i) |
Printf("%.1f", 1+2i)→ (1.0+2.0i) |
| 字符串与字节切片 | %s |
字符串或字节切片的原始内容 | Printf("%s", []byte("Hello"))→ Hello |
%q |
双引号括起来的字符串 | Printf("%q", "你好")→ "你好" |
|
%x |
十六进制(小写,每字节两个字符) | Printf("%x", "Go")→ 476f |
|
%X |
十六进制(大写,每字节两个字符) | Printf("%X", "Go")→ 476F |
|
| 指针 | %p |
指针地址(十六进制表示,带0x前缀) | Printf("%p", &x)→ 0xc0000b8000 |
| 宽度与精度 | %5d |
最小宽度5,右对齐 | `fmt.Printf("右对齐: |
%-5d |
最小宽度5,左对齐 | `fmt.Printf("左对齐: | |
%05d |
最小宽度5,不足补0 | Printf("%05d", 12)→ 00012 |
|
%5.2f |
总宽5,小数点后2位 | Printf("%5.2f", 3.14159)→ 3.14 |
|
%*.*f |
宽度和精度从参数获取 | Printf("%*.*f", 5, 2, 3.14159)→ 3.14 |
还有一种用得多的就是格式化后,赋值给变量方便后续使用。
Sprintf: 返回string类型,获取格式化结果以便后续使用。
go
package main
import "fmt"
func main() {
name := fmt.Sprintf("%v", "你好")
fmt.Println(name) //你好
}
输入
主要使用Scan家族函数
go
package main
import "fmt"
func main() {
fmt.Println("请输入你的名字:")
var (
name string
age int
address string
)
//直接输入
fmt.Scan(&name)
fmt.Println("请输入你的年龄:")
//格式化输入
fmt.Scanf("%d", &age)
fmt.Println("请输入你的地址:")
//读取到换行结束
fmt.Scanln(&address)
fmt.Printf("name: %s age: %d address: %s\n", name, age, address)
}

这类函数也有返回值:
go
package main
import "fmt"
func main() {
var name string
var age int
var score float64
fmt.Print("输入(姓名 年龄 分数): ")
n, err := fmt.Scan(&name, &age, &score)
fmt.Printf("读取了 %d 个参数\n", n) // 3
fmt.Printf("姓名: %s, 年龄: %d, 分数: %.1f\n", name, age, score)
fmt.Printf("错误: %v\n", err)
}
