1.变量的声明
// 1.显示声明 var a int var b int = 20 // 2.隐式声明 var c = 30 // 自动推断 c 为 int 类型 // 3.短变量声明 d := 40 // 也是自动推断 d 为 int 类型 // 4.多变量声明 var e, f, g int // 同时声明多个同类型变量 var h, i, j = 1, "hello", 3.14 // 同时声明多个不同类型变量 var k, l, m := 1, "world", 3.14 // 同时声明多个短变量 // 5.匿名变量 _, n := 10, 20 // 忽略第一个值,且不会占内存 // 6.常量声明 const pi = 3.14
2.fmt.Printf函数占位符
通用占位符
- %v:按变量的值原样输出(最常用)
- %+v:类似%v,但对结构体会包含字段名和值
- %#v:输出变量的 Go 语法表示(包括包、字段名和值)
- %T:输出变量的类型
- %%:输出百分号%
fmt.Printf("%v\n", 123) // 输出: 123 fmt.Printf("%+v\n", struct{name string}{"Alice"}) // 输出: {name:Alice} fmt.Printf("%#v\n", []int{1, 2, 3}) // 输出: []int{1, 2, 3} fmt.Printf("%T\n", 123) // 输出: int fmt.Printf("%%\n") // 输出: %
整数类型
- %b:二进制表示
- %c:对应 Unicode 编码的字符
- %d:十进制表示
- %o:八进制表示
- %x:十六进制表示(小写)
- %X:十六进制表示(大写)
- %U:Unicode 格式(如 U+1234)
fmt.Printf("%b\n", 10) // 输出: 1010 fmt.Printf("%c\n", 65) // 输出: A fmt.Printf("%d\n", 123) // 输出: 123 fmt.Printf("%o\n", 8) // 输出: 10 fmt.Printf("%x\n", 255) // 输出: ff fmt.Printf("%X\n", 255) // 输出: FF fmt.Printf("%U\n", 'A') // 输出: U+0041
浮点数与复数
- %f:十进制格式(默认精度 6 位)
- %.nf:指定小数点后保留 n 位
- %e:科学计数法(小写 e)
- %E:科学计数法(大写 E)
- %g:根据数值的长度自动选择 %e 或 %f
- %G:根据数值的长度自动选择 %E 或 %F
fmt.Printf("%f\n", 123.456) // 输出: 123.456000 fmt.Printf("%.2f\n", 123.456) // 输出: 123.46 fmt.Printf("%e\n", 123456.0) // 输出: 1.234560e+05 fmt.Printf("%E\n", 123456.0) // 输出: 1.234560E+05 fmt.Printf("%g\n", 123456.0) // 输出: 123456
字符串与切片
- %s:字符串或切片的文本表示
- %q:双引号括起的字符串
- %x:字符串的十六进制表示(小写)
- %X:字符串的十六进制表示(大写)
fmt.Printf("%s\n", "hello") // 输出: hello fmt.Printf("%q\n", "hello") // 输出: "hello" fmt.Printf("%x\n", "hello") // 输出: 68656c6c6f fmt.Printf("%X\n", "hello") // 输出: 68656C6C6F
指针
- %p:指针的十六进制表示
p := &[]int{1, 2, 3} fmt.Printf("%p\n", p) // 输出: 0xc0000120a0 (示例地址)
布尔值
- %t:布尔值 true 或 false
fmt.Printf("%t\n", true) // 输出: true fmt.Printf("%t\n", false) // 输出: false
宽度与对齐
- %5d:宽度为 5,右对齐
- %-5d:宽度为 5,左对齐
fmt.Printf("%5d\n", 42) // 输出: 42 fmt.Printf("%-5d\n", 42) // 输出: 42
零填充
- %05d:宽度为 5,前面用 0 填充
fmt.Printf("%05d\n", 42) // 输出: 00042
3.结构体
定义形式
type Person struct { Name string Age int }
结构体的赋值
// 1.使用字段名赋值(推荐) p1 := Person{Name: "Alice", Age: 25} fmt.Println(p1) // 输出: {Alice 25} // 2.直接按照字段顺序赋值,必选按照结构体字段顺序 p2 := Person{"Bob", 30} fmt.Println(p2) // 输出: {Bob 30} // 3.使用 new 关键字 p3 := new(Person) // p3 是 *Person 类型 p3.Name = "Charlie" // 也可以是 (*p3).Name 访问Name字段 p3.Age = 35 fmt.Println(*p3) // 输出: {Charlie 35} // 4.使用指针 & 直接赋值 p4 := &Person{Name: "David", Age: 40} fmt.Println(p4) // 输出: &{David 40} fmt.Println(*p4) // 输出: {David 40} // 5.使用 var 关键字,会根据类型初始化字段为""、0或false var p5 Person p5.Name = "Eve" p5.Age = 45 fmt.Println(p5) // 输出: {Eve 45}
结构体的嵌套
type Address struct { City, Country string } type User struct { Name string Age int Address Address } user := User{ Name: "Frank", Age: 28, Address: Address{ City: "Beijing", Country: "China", }, } fmt.Println(user) // 输出: {Frank 28 {Beijing China}}
结构体的方法
在 Go 语言中,方法不能写在结构体定义的内部,而是必须在全局作用域中定义。Go 不是面向对象语言,不支持在结构体内部直接定义方法,所以方法需要写在结构体之外,但仍然与该结构体相关联。
func (p Person) SayHello() { fmt.Println("Hello, my name is", p.Name) } p := Person{Name: "Grace", Age: 22} p.SayHello() // 输出: Hello, my name is Grace
如果需要修改结构体内部的字段,需要使用指针接收者 *Person
func (p *Person) SetAge(newAge int) { p.Age = newAge } p := Person{Name: "Henry", Age: 20} p.SetAge(26) fmt.Println(p) // 输出: {Henry 26}