Skip to content

语法基础对比速览

本章快速对比Python与Go语法:变量声明、类型系统、数据类型、控制流、函数。重点:Go静态类型+零值机制 vs Python动态类型,理解两者核心差异。

前置知识:Python基础语法 学习目标:能读懂Go代码、理解Go类型系统、掌握语法对应关系


Python是动态类型,变量是引用:

# Python - 变量是标签
x = 10 # 创建int对象10,x指向它
y = x # y也指向同一个int对象10
x = 20 # x指向新的int对象20,y仍指向10
print(x) # 20
print(y) # 10
# 类型随时变化
x = "hello"
print(x) # hello

变量本身无类型,类型属于对象。

Go是静态类型,变量有类型:

// Go - 变量是容器
var x int = 10 // x是int类型容器,值为10
var y int = x // y是新的int容器,值为20的副本
x = 20 // x的值变为20,y不变
fmt.Println(x) // 20
fmt.Println(y) // 10
// 类型固定,不可改变
// x = "hello" // 编译错误:无法将string赋值给int

方式一:var + 类型 + 初始值

var age int = 25
var name string = "Alice"
var isStudent bool = true

方式二:var + 类型(零值初始化)

var age int // 0
var name string // ""
var isStudent bool // false
// 常用:声明后赋值
var age int
age = 25

方式三:短变量声明(函数内)

func main() {
// 最常用方式
name := "Alice" // 推导为string
age := 25 // 推导为int
isStudent := true // 推导为bool
// 多变量
x, y := 1, 2
fmt.Println(name, age, isStudent) // Alice 25 true
}

方式四:var()批量声明

var (
name string = "Alice"
age int = 25
city string = "Beijing"
)
PythonGo说明
x = 10var x int = 10显式类型
x = 10x := 10类型推导
x, y = 1, 2x, y := 1, 2多赋值
x = y = 10var x, y int = 10, 10链式赋值
无法声明无初始值var x intGo零值机制

Go的变量总有默认值:

var i int // 0
var f float64 // 0.0
var b bool // false
var s string // ""
var ptr *int // nil(指针)
var slice []int // nil
var m map[string]int // nil

Python无此机制,未初始化的变量会报错。

Go有指针,Python无:

// &取地址,*解引用
x := 10
p := &x // p是指向x的指针,类型*int
fmt.Println(p) // 打印地址,如0xc0000a6000
fmt.Println(*p) // 10,解引用获取值
*p = 20 // 通过指针修改x
fmt.Println(x) // 20

Python无法获取变量地址,但可以用id()模拟:

x = 10
print(id(x)) # 类似地址
# Python不暴露指针机制

本节目的:对比Python/Go数据类型、理解Go固定宽度整数的优缺点

Go整数类型(固定宽度):

类型有符号范围Python对应
int8是-128~127-
int16是-32768~32767-
int32是-21亿~21亿int
int64是很大int
uint8否0~255-
uint16否0~65535-
uint32否0~42亿-
uint64否很大-

常用简写:

int // 平台相关(32或64位)
uint // 平台相关
uintptr // 足够大以保存指针

与Python的差异:

  • Python int是任意精度,Go int是固定精度
  • Go对溢出严格处理,Python自动扩展
var i int32 = 2147483647
i += 1 // 溢出:变成-2147483648
i = 2147483647
i += 1 # Python自动扩展:2147483648

字面量:

a := 100 // 十进制
b := 0xFF // 十六进制 (255)
c := 0o777 // 八进制 (511)
d := 0b1010 // 二进制 (10)
// 下划线分隔(Go 1.13+)
big := 1_000_000 // 1000000
hex := 0xFFFF_FFFF // 4294967295
类型精度Python对应
float326-7位十进制精度float
float6415-17位精度float
var f1 float64 = 3.141592653589793
var f2 float32 = 3.14159
fmt.Printf("%.10f\n", f1) // 3.1415926536
fmt.Printf("%.7f\n", f2) // 3.1415900

特殊值:

inf := math.Inf(1) // 正无穷
ninf := math.Inf(-1) // 负无穷
nan := math.NaN() // 非数
// NaN比较(特殊规则)
math.NaN() == math.NaN() // false
math.IsNaN(nan) // true
var b1 bool = true
var b2 bool = false
// 短声明
active := true
deleted := false
// 布尔运算
and := true && false // false
or := true || false // true
not := !true // false

Python对应:True, False, and, or, not

var s1 string = "Hello"
var s2 string = "世界"
// 字符串是UTF-8编码的字节序列
s3 := "Hello, 世界"
fmt.Println(len(s3)) // 13(字节数)
fmt.Println(utf8.RuneCountInString(s3)) // 9(字符数)

Python对应:str类型,Unicode原生支持。

字符串不可变:

s := "hello"
// s[0] = 'H' // 编译错误:无法修改字符串
// 必须创建新字符串
s2 := "H" + s[1:] // "Hello"

Python字符串也不可变,但可以重新赋值。

var c1 byte = 'a' // ASCII
var c2 rune = '中' // Unicode码点
fmt.Printf("%c %d\n", c1, c1) // a 97
fmt.Printf("%c %U\n", c2, c2) // 中 U+4E2D
// rune是int32的别名
c3 := rune(65) // 'A'

Python对应:ord()和chr()

c = ord('a') # 97
c = chr(97) # 'a'
const PI = 3.14159
const NAME = "Go"
// 批量声明
const (
STATUS_OK = 200
STATUS_NOT_FOUND = 404
STATUS_SERVER_ERROR = 500
)
// iota:常量生成器
const (
Monday = iota // 0
Tuesday // 1
Wednesday // 2
// ...
)

Python对应:True, False, None是内置常量。


本节目的:掌握Go控制流语法、对照Python理解差异

Python版本:

x = 10
if x > 0:
print("正数")
elif x < 0:
print("负数")
else:
print("零")

Go版本:

x := 10
if x > 0 {
fmt.Println("正数")
} else if x < 0 {
fmt.Println("负数")
} else {
fmt.Println("零")
}

关键差异:

  1. 条件不需要括号
  2. 左大括号必须在同一行
// 正确
if x > 0 {
fmt.Println("正数")
}
// 错误
if x > 0
{
fmt.Println("正数")
}

if与初始化:

// Go特有:if中可以初始化变量
if err := doSomething(); err != nil {
fmt.Println("错误:", err)
}
// Python无等效语法,需要先赋值
err = do_something()
if err:
print("错误:", err)

常见模式:

if file, err := os.Open("test.txt"); err != nil {
fmt.Println("打开失败:", err)
} else {
// file在此处可用
data := make([]byte, 100)
file.Read(data)
file.Close()
}

Python的for:

# 遍历范围
for i in range(5):
print(i) # 0 1 2 3 4
# 遍历列表
for item in [1, 2, 3]:
print(item)

Go只有for(无while关键字):

// 经典for
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// 模拟while
i := 0
for i < 5 {
fmt.Println(i)
i++
}
// 无限循环
for {
fmt.Println("无限循环")
if condition {
break
}
}
// 遍历切片
items := []int{1, 2, 3}
for index, value := range items {
fmt.Printf("%d: %d\n", index, value)
}
// 遍历字符串(UTF-8)
str := "Hello世界"
for i, r := range str {
fmt.Printf("%d: %c\n", i, r)
}

range返回值:

类型返回值
切片/数组index, value
Mapkey, value
字符串index, rune
Channelvalue

Python的match(3.10+):

day = "Monday"
match day:
case "Monday":
print("周一")
case "Friday":
print("周五")
case _:
print("其他")

Go的switch:

day := "Monday"
switch day {
case "Monday":
fmt.Println("周一")
case "Friday":
fmt.Println("周五")
default:
fmt.Println("其他")
}

Go的switch特点:

  1. 不需要break(自动break)
  2. 可以多个值
  3. 可以省略条件(当if-else用)
// 多个值
switch day {
case "Monday", "Tuesday", "Wednesday":
fmt.Println("工作日")
case "Saturday", "Sunday":
fmt.Println("周末")
}
// 无条件switch(替代if-else链)
score := 85
switch {
case score >= 90:
fmt.Println("A")
case score >= 80:
fmt.Println("B")
case score >= 60:
fmt.Println("C")
default:
fmt.Println("D")
}
// fallthrough:继续执行下一个case
switch 2 {
case 1:
fmt.Println("one")
fallthrough
case 2:
fmt.Println("two")
fallthrough
case 3:
fmt.Println("three")
}
// 输出: two three

本节目的:理解Go函数语法、多返回值、错误处理模式

Python版本:

def add(a, b):
return a + b
result = add(1, 2)
print(result) # 3

Go版本:

func add(a int, b int) int {
return a + b
}
result := add(1, 2)
fmt.Println(result) // 3

函数声明语法:

func 函数名(参数1 类型1, 参数2 类型2) 返回类型 {
// 函数体
return 值
}

Go最强大的特性之一:

// Python只能返回一个值
def divide(a, b):
return a // b # 如果用异常处理
// Go多返回值
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("除数不能为零")
}
return a / b, nil
}
// 调用
quotient, err := divide(10, 2)
if err != nil {
fmt.Println("错误:", err)
} else {
fmt.Println("结果:", quotient) // 5
}

忽略返回值:

result, _ := divide(10, 2) // 忽略error
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return // 返回x和y(命名返回值)
}
// 调用
a, b := split(100)
fmt.Println(a, b) // 44 56

Python无等效特性。

// Python
def sum(*args):
total = 0
for n in args:
total += n
return total
print(sum(1, 2, 3)) # 6
// Go
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
fmt.Println(sum(1, 2, 3)) // 6
// Go函数是一等公民(first-class)
type Operation func(int, int) int
func add(a, b int) int { return a + b }
func multiply(a, b int) int { return a * b }
func calculate(op Operation, a, b int) int {
return op(a, b)
}
func main() {
result := calculate(add, 3, 4)
fmt.Println(result) // 7
result = calculate(multiply, 3, 4)
fmt.Println(result) // 12
}

Python同样支持函数作为参数。


  1. 优先用短声明:函数内 x := 10 比 var x int = 10 更简洁;函数外用 var
  2. 零值是你的朋友:声明后直接使用的变量用 var x int,不必显式赋0
  3. 整数用int即可:除非需要特定宽度,Go的int在64位系统是64位,足够日常使用
  4. for循环是唯一的循环:Go没有while,用for实现所有循环模式(死循环for {})
  5. 多返回值配合error:Go没有异常机制,函数错误通过返回error类型表达

PythonGo
x = 10var x int = 10 或 x := 10
int, float, str, boolint, float64, string, bool
if x > 0:if x > 0 { }
for i in range(n):for i := 0; i < n; i++ { }
for item in list:for _, item := range list { }
match x:switch x { case ...: }
def f(a, b): return a + bfunc f(a, b int) int { return a + b }
单一返回值多返回值 func f() (int, error)
无等效命名返回值、指针、可变参数

  1. 声明int、float64、string、bool变量,用短声明和var两种方式
  2. 写一个函数,返回两个整数的和与积
  3. 写一个可变参数函数,计算任意数量整数的平均值
  4. 模拟Python的enumerate,用range遍历切片并打印索引和值
  5. 用switch实现一个简单的计算器(+、-、*、/)