Go 基础语法 - 变量与类型
2025/5/22大约 4 分钟
当然可以!以下是基于你当前环境(Linux Mint XFCE、Go 1.22.2、项目目录 /home/liumangmang/GolandProjects)整理的 Go 语言基础语法实践步骤,涵盖:
- 基本类型
- 变量声明
:=简短声明- 指针
newvsmake
我们将通过一个可运行的示例程序来演示这些概念。
✅ 步骤 1:创建练习项目
打开终端:
cd /home/liumangmang/GolandProjects
mkdir go-basics && cd go-basics
go mod init go-basics✅ 步骤 2:编写示例代码(main.go)
使用你喜欢的编辑器(或 GoLand)创建 main.go:
nano main.go粘贴以下完整示例代码(包含注释说明):
package main
import "fmt"
func main() {
// ========== 1. 基本类型 ==========
var a int = 42
var b float64 = 3.14
var c bool = true
var d string = "Hello, Go!"
fmt.Println("基本类型:")
fmt.Printf("int: %d\n", a)
fmt.Printf("float64: %.2f\n", b)
fmt.Printf("bool: %t\n", c)
fmt.Printf("string: %s\n", d)
// ========== 2. 变量声明方式 ==========
// 方式1:var 声明(可带或不带初始值)
var x int
x = 100
var y = 200 // 类型自动推导
// 方式2:批量声明
var (
name = "Liu"
age = 30
height = 175.5
isAdmin = true
)
fmt.Println("\n变量声明:")
fmt.Println("x =", x, ", y =", y)
fmt.Println("name:", name, "age:", age, "height:", height, "isAdmin:", isAdmin)
// ========== 3. := 简短声明(仅在函数内部可用)==========
z := 999 // 自动推导为 int
message := "Use := !" // 自动推导为 string
fmt.Println("\n简短声明 (:=):")
fmt.Println("z =", z, ", message =", message)
// 注意::= 必须至少声明一个新变量
// 下面这行会报错:no new variables on left side of :=
// z := 888 // ❌ 错误!
// 但可以这样混合新旧变量:
w, z := "new", 888 // w 是新的,z 是重新赋值(shadowing)
fmt.Println("w =", w, ", z =", z)
// ========== 4. 指针 ==========
p := &a // p 是指向 a 的指针(*int 类型)
fmt.Println("\n指针:")
fmt.Printf("a 的值: %d\n", a)
fmt.Printf("a 的地址: %p\n", &a)
fmt.Printf("p 的值(即 a 的地址): %p\n", p)
fmt.Printf("*p(解引用): %d\n", *p)
*p = 1000 // 通过指针修改 a 的值
fmt.Println("修改后 a =", a)
// ========== 5. new vs make ==========
// new(T) → 分配零值内存,返回 *T
ptrInt := new(int) // *int,值为 0
*ptrInt = 42
fmt.Println("\nnew(int):", *ptrInt)
// make 仅用于 slice, map, chan —— 返回初始化后的 T(不是指针!)
s := make([]int, 3) // 长度为3的 slice,元素为 [0 0 0]
m := make(map[string]int) // 空 map
ch := make(chan int, 2) // 缓冲通道
s[0] = 10
m["count"] = 1
ch <- 100
fmt.Println("make(slice):", s)
fmt.Println("make(map):", m)
fmt.Println("make(chan) 示例(略去接收)")
// ⚠️ 不能对 slice/map/chan 使用 new!
// bad := new([]int) // 这是一个 *[]int,但底层数组未初始化,不能直接用!
}保存并退出(Ctrl+O → Enter → Ctrl+X)。
✅ 步骤 3:格式化 & 运行
# 格式化代码(虽然我们写得很规范,但习惯要好)
go fmt
# 运行程序
go run .你应该看到类似输出:
基本类型:
int: 42
float64: 3.14
bool: true
string: Hello, Go!
变量声明:
x = 100 , y = 200
name: Liu age: 30 height: 175.5 isAdmin: true
简短声明 (:=):
z = 999 , message = Use := !
w = new , z = 888
指针:
a 的值: 42
a 的地址: 0xc0000b4008
p 的值(即 a 的地址): 0xc0000b4008
*p(解引用): 42
修改后 a = 1000
new(int): 42
make(slice): [10 0 0]
make(map): map[count:1]
make(chan) 示例(略去接收)🔍 关键知识点总结(对比 Java)
| 概念 | Go 行为 | Java 对比 |
|---|---|---|
| 变量声明 | var x int = 1 或 x := 1 | int x = 1;(必须指定类型或用 var + 初始化) |
| := | 函数内快速声明+初始化,至少一个新变量 | Java 无直接等价(Java 10+ 有 var,但非声明新作用域) |
| 指针 | 显式支持 *T 和 &x | Java 无显式指针(对象引用类似,但不可运算) |
| new | 分配零值内存,返回指针 *T | 类似 new Object(),但 Go 的 new 只用于值类型 |
| make | 专用于 slice/map/chan 的初始化(返回 T,非指针) | Java 中 new ArrayList<>() 等构造器承担类似职责 |
💡 提醒:Go 中 slice / map / chan 是引用类型,传递时是“引用语义”,但它们本身不是指针。
make是它们的正确初始化方式。
✅ 下一步建议
- 在 GoLand 中打开这个项目,尝试修改变量、加断点调试指针。
- 尝试注释掉
*p = 1000,观察a是否变化。 - 尝试
bad := new([]int); bad[0] = 1,看是否会 panic(会!因为底层未分配)。
如果你希望我继续讲解 结构体、方法、接口、goroutine 等内容,随时告诉我!祝你 Go 学习顺利 🚀
