# 基本语法
变量声明
基本变量声明
var关键字声明
package main
import "fmt"
func main() {
// 声明单个变量
var name string
var age int
var height float64
// 赋值
name = "Alice"
age = 25
height = 1.68
fmt.Printf("姓名: %s, 年龄: %d, 身高: %.2f\n", name, age, height)
}
go run var_basic.go
声明时初始化
package main
import "fmt"
func main() {
// 声明并初始化
var name string = "Bob"
var age int = 30
var isStudent bool = false
fmt.Printf("姓名: %s, 年龄: %d, 学生: %t\n", name, age, isStudent)
}
go run var_init.go
类型推断
package main
import "fmt"
func main() {
// Go可以自动推断类型
var name = "Charlie" // string
var age = 35 // int
var salary = 5000.50 // float64
fmt.Printf("类型: %T, 值: %v\n", name, name)
fmt.Printf("类型: %T, 值: %v\n", age, age)
fmt.Printf("类型: %T, 值: %v\n", salary, salary)
}
go run var_inference.go
短变量声明
使用:=操作符
package main
import "fmt"
func main() {
// 短变量声明(只能在函数内使用)
name := "David"
age := 28
isMarried := true
fmt.Printf("姓名: %s, 年龄: %d, 已婚: %t\n", name, age, isMarried)
}
go run short_var.go
多变量声明
package main
import "fmt"
func main() {
// 多变量同时声明
var a, b, c int = 1, 2, 3
x, y, z := "hello", 3.14, true
fmt.Printf("a=%d, b=%d, c=%d\n", a, b, c)
fmt.Printf("x=%s, y=%.2f, z=%t\n", x, y, z)
}
go run multi_var.go
变量作用域
包级变量
package main
import "fmt"
// 包级变量
var globalVar = "我是全局变量"
func main() {
// 函数级变量
localVar := "我是局部变量"
fmt.Println(globalVar)
fmt.Println(localVar)
// 块级作用域
if true {
blockVar := "我是块级变量"
fmt.Println(blockVar)
}
// fmt.Println(blockVar) // 这里会报错,blockVar不可访问
}
go run scope.go
常量声明
基本常量
const关键字
package main
import "fmt"
func main() {
// 声明常量
const pi = 3.14159
const greeting = "Hello, World!"
const maxUsers = 1000
fmt.Printf("π = %.5f\n", pi)
fmt.Printf("问候语: %s\n", greeting)
fmt.Printf("最大用户数: %d\n", maxUsers)
}
go run const_basic.go
类型化常量
package main
import "fmt"
func main() {
// 指定类型的常量
const name string = "Go语言"
const version float32 = 1.19
const isOpen bool = true
fmt.Printf("语言: %s (类型: %T)\n", name, name)
fmt.Printf("版本: %.2f (类型: %T)\n", version, version)
fmt.Printf("开源: %t (类型: %T)\n", isOpen, isOpen)
}
go run const_typed.go
常量组
批量声明常量
package main
import "fmt"
func main() {
// 常量组
const (
StatusOK = 200
StatusNotFound = 404
StatusError = 500
)
fmt.Printf("成功状态码: %d\n", StatusOK)
fmt.Printf("未找到状态码: %d\n", StatusNotFound)
fmt.Printf("错误状态码: %d\n", StatusError)
}
go run const_group.go
iota枚举器
使用iota创建枚举
package main
import "fmt"
func main() {
// iota枚举器
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
fmt.Printf("星期日: %d\n", Sunday)
fmt.Printf("星期一: %d\n", Monday)
fmt.Printf("星期六: %d\n", Saturday)
}
go run iota_basic.go
iota高级用法
package main
import "fmt"
func main() {
// iota表达式
const (
_ = iota // 0 (忽略)
KB = 1 << (10 * iota) // 1 << 10 = 1024
MB // 1 << 20 = 1048576
GB // 1 << 30 = 1073741824
)
fmt.Printf("1 KB = %d bytes\n", KB)
fmt.Printf("1 MB = %d bytes\n", MB)
fmt.Printf("1 GB = %d bytes\n", GB)
}
go run iota_advanced.go
数据类型
基本数据类型
整数类型
package main
import (
"fmt"
"unsafe"
)
func main() {
// 有符号整数
var i8 int8 = 127
var i16 int16 = 32767
var i32 int32 = 2147483647
var i64 int64 = 9223372036854775807
// 无符号整数
var ui8 uint8 = 255
var ui16 uint16 = 65535
var ui32 uint32 = 4294967295
var ui64 uint64 = 18446744073709551615
// 平台相关
var i int = 42
var ui uint = 42
fmt.Printf("int8: %d (大小: %d字节)\n", i8, unsafe.Sizeof(i8))
fmt.Printf("int16: %d (大小: %d字节)\n", i16, unsafe.Sizeof(i16))
fmt.Printf("int32: %d (大小: %d字节)\n", i32, unsafe.Sizeof(i32))
fmt.Printf("int64: %d (大小: %d字节)\n", i64, unsafe.Sizeof(i64))
fmt.Printf("uint8: %d (大小: %d字节)\n", ui8, unsafe.Sizeof(ui8))
fmt.Printf("int: %d (大小: %d字节)\n", i, unsafe.Sizeof(i))
fmt.Printf("uint: %d (大小: %d字节)\n", ui, unsafe.Sizeof(ui))
}
go run int_types.go
浮点数类型
package main
import (
"fmt"
"math"
)
func main() {
// 浮点数类型
var f32 float32 = 3.14159
var f64 float64 = 3.141592653589793
fmt.Printf("float32: %.7f\n", f32)
fmt.Printf("float64: %.15f\n", f64)
// 特殊浮点值
fmt.Printf("正无穷: %f\n", math.Inf(1))
fmt.Printf("负无穷: %f\n", math.Inf(-1))
fmt.Printf("NaN: %f\n", math.NaN())
// 浮点数精度比较
a := 0.1 + 0.2
b := 0.3
fmt.Printf("0.1 + 0.2 = %.17f\n", a)
fmt.Printf("0.3 = %.17f\n", b)
fmt.Printf("相等吗? %t\n", a == b)
// 正确的浮点数比较
epsilon := 1e-9
fmt.Printf("近似相等吗? %t\n", math.Abs(a-b) < epsilon)
}
go run float_types.go
复数类型
package main
import "fmt"
func main() {
// 复数类型
var c64 complex64 = 1 + 2i
var c128 complex128 = 3 + 4i
fmt.Printf("complex64: %v\n", c64)
fmt.Printf("complex128: %v\n", c128)
// 复数运算
sum := c64 + complex64(c128)
fmt.Printf("复数相加: %v\n", sum)
// 获取实部和虚部
fmt.Printf("实部: %.2f, 虚部: %.2f\n", real(c128), imag(c128))
// 使用complex函数创建复数
c := complex(5, 6)
fmt.Printf("complex(5, 6) = %v\n", c)
}
go run complex_types.go
字符串类型
字符串基础
package main
import "fmt"
func main() {
// 字符串声明
var str1 string = "Hello, World!"
str2 := "Go语言"
fmt.Printf("字符串1: %s\n", str1)
fmt.Printf("字符串2: %s\n", str2)
fmt.Printf("字符串长度: %d\n", len(str2))
// 字符串是不可变的
// str1[0] = 'h' // 这会报错
// 字符串拼接
combined := str1 + " " + str2
fmt.Printf("拼接结果: %s\n", combined)
}
go run string_basic.go
原始字符串
package main
import "fmt"
func main() {
// 原始字符串(反引号)
rawStr := `这是一个原始字符串
包含换行符\n和反斜杠\\`
fmt.Println("原始字符串:")
fmt.Println(rawStr)
// 多行字符串
multiLine := `
SELECT *
FROM users
WHERE age > 18
ORDER BY name
`
fmt.Println("SQL查询:")
fmt.Println(multiLine)
}
go run string_raw.go
字符串操作
package main
import (
"fmt"
"strings"
"strconv"
)
func main() {
text := "Hello, Go Programming!"
// 字符串查找
fmt.Printf("包含'Go': %t\n", strings.Contains(text, "Go"))
fmt.Printf("'Go'的位置: %d\n", strings.Index(text, "Go"))
// 字符串替换
replaced := strings.Replace(text, "Go", "Golang", 1)
fmt.Printf("替换后: %s\n", replaced)
// 字符串分割
parts := strings.Split(text, " ")
fmt.Printf("分割结果: %v\n", parts)
// 大小写转换
fmt.Printf("大写: %s\n", strings.ToUpper(text))
fmt.Printf("小写: %s\n", strings.ToLower(text))
// 字符串和数字转换
numStr := "123"
num, err := strconv.Atoi(numStr)
if err == nil {
fmt.Printf("字符串'%s'转为数字: %d\n", numStr, num)
}
str := strconv.Itoa(456)
fmt.Printf("数字456转为字符串: '%s'\n", str)
}
go run string_ops.go
布尔类型
布尔值操作
package main
import "fmt"
func main() {
// 布尔类型
var isTrue bool = true
var isFalse bool = false
var defaultBool bool // 默认值为false
fmt.Printf("isTrue: %t\n", isTrue)
fmt.Printf("isFalse: %t\n", isFalse)
fmt.Printf("defaultBool: %t\n", defaultBool)
// 布尔运算
fmt.Printf("true && false = %t\n", true && false)
fmt.Printf("true || false = %t\n", true || false)
fmt.Printf("!true = %t\n", !true)
// 比较运算产生布尔值
a, b := 10, 20
fmt.Printf("%d > %d = %t\n", a, b, a > b)
fmt.Printf("%d == %d = %t\n", a, b, a == b)
fmt.Printf("%d != %d = %t\n", a, b, a != b)
}
go run bool_type.go
运算符
算术运算符
基本算术运算
package main
import "fmt"
func main() {
a, b := 15, 4
fmt.Printf("a = %d, b = %d\n", a, b)
fmt.Printf("a + b = %d\n", a+b) // 加法
fmt.Printf("a - b = %d\n", a-b) // 减法
fmt.Printf("a * b = %d\n", a*b) // 乘法
fmt.Printf("a / b = %d\n", a/b) // 除法(整数除法)
fmt.Printf("a %% b = %d\n", a%b) // 取模
// 浮点数除法
x, y := 15.0, 4.0
fmt.Printf("%.1f / %.1f = %.2f\n", x, y, x/y)
}
go run arithmetic.go
自增自减运算符
package main
import "fmt"
func main() {
count := 10
fmt.Printf("初始值: %d\n", count)
count++ // 自增
fmt.Printf("自增后: %d\n", count)
count-- // 自减
fmt.Printf("自减后: %d\n", count)
// 注意:Go中++和--是语句,不是表达式
// fmt.Println(count++) // 这会报错
// 复合赋值运算符
count += 5
fmt.Printf("count += 5: %d\n", count)
count -= 3
fmt.Printf("count -= 3: %d\n", count)
count *= 2
fmt.Printf("count *= 2: %d\n", count)
count /= 4
fmt.Printf("count /= 4: %d\n", count)
}
go run increment.go
比较运算符
数值比较
package main
import "fmt"
func main() {
a, b := 10, 20
fmt.Printf("a = %d, b = %d\n", a, b)
fmt.Printf("a == b: %t\n", a == b) // 等于
fmt.Printf("a != b: %t\n", a != b) // 不等于
fmt.Printf("a < b: %t\n", a < b) // 小于
fmt.Printf("a <= b: %t\n", a <= b) // 小于等于
fmt.Printf("a > b: %t\n", a > b) // 大于
fmt.Printf("a >= b: %t\n", a >= b) // 大于等于
// 字符串比较
str1, str2 := "apple", "banana"
fmt.Printf("\n字符串比较:\n")
fmt.Printf("'%s' < '%s': %t\n", str1, str2, str1 < str2)
fmt.Printf("'%s' == '%s': %t\n", str1, str2, str1 == str2)
}
go run comparison.go
逻辑运算符
逻辑运算
package main
import "fmt"
func main() {
a, b := true, false
fmt.Printf("a = %t, b = %t\n", a, b)
fmt.Printf("a && b: %t\n", a && b) // 逻辑与
fmt.Printf("a || b: %t\n", a || b) // 逻辑或
fmt.Printf("!a: %t\n", !a) // 逻辑非
fmt.Printf("!b: %t\n", !b)
// 短路求值
fmt.Println("\n短路求值演示:")
x := 0
if x != 0 && 10/x > 1 {
fmt.Println("这不会执行")
} else {
fmt.Println("短路求值避免了除零错误")
}
}
go run logical.go
位运算符
位操作
package main
import "fmt"
func main() {
a, b := 12, 10 // 二进制: 1100, 1010
fmt.Printf("a = %d (二进制: %08b)\n", a, a)
fmt.Printf("b = %d (二进制: %08b)\n", b, b)
fmt.Printf("a & b = %d (二进制: %08b)\n", a&b, a&b) // 按位与
fmt.Printf("a | b = %d (二进制: %08b)\n", a|b, a|b) // 按位或
fmt.Printf("a ^ b = %d (二进制: %08b)\n", a^b, a^b) // 按位异或
fmt.Printf("^a = %d (二进制: %08b)\n", ^a, uint8(^a)) // 按位取反
// 位移运算
fmt.Printf("a << 2 = %d (二进制: %08b)\n", a<<2, a<<2) // 左移
fmt.Printf("a >> 2 = %d (二进制: %08b)\n", a>>2, a>>2) // 右移
// 位运算的实际应用
fmt.Println("\n位运算应用:")
// 判断奇偶
num := 15
if num&1 == 0 {
fmt.Printf("%d 是偶数\n", num)
} else {
fmt.Printf("%d 是奇数\n", num)
}
// 快速乘除2的幂
fmt.Printf("%d * 4 = %d (使用左移)\n", num, num<<2)
fmt.Printf("%d / 4 = %d (使用右移)\n", num, num>>2)
}
go run bitwise.go
赋值运算符
各种赋值方式
package main
import "fmt"
func main() {
var x int
// 基本赋值
x = 10
fmt.Printf("x = %d\n", x)
// 复合赋值运算符
x += 5 // x = x + 5
fmt.Printf("x += 5: %d\n", x)
x -= 3 // x = x - 3
fmt.Printf("x -= 3: %d\n", x)
x *= 2 // x = x * 2
fmt.Printf("x *= 2: %d\n", x)
x /= 4 // x = x / 4
fmt.Printf("x /= 4: %d\n", x)
x %= 3 // x = x % 3
fmt.Printf("x %%= 3: %d\n", x)
// 位运算赋值
x = 12
x &= 10 // x = x & 10
fmt.Printf("x &= 10: %d\n", x)
x |= 5 // x = x | 5
fmt.Printf("x |= 5: %d\n", x)
x ^= 3 // x = x ^ 3
fmt.Printf("x ^= 3: %d\n", x)
x <<= 1 // x = x << 1
fmt.Printf("x <<= 1: %d\n", x)
x >>= 2 // x = x >> 2
fmt.Printf("x >>= 2: %d\n", x)
}
go run assignment.go
类型转换
显式类型转换
数值类型转换
package main
import "fmt"
func main() {
// 整数类型转换
var i32 int32 = 42
var i64 int64 = int64(i32) // int32 -> int64
var i int = int(i64) // int64 -> int
fmt.Printf("int32: %d, int64: %d, int: %d\n", i32, i64, i)
// 浮点数转换
var f32 float32 = 3.14
var f64 float64 = float64(f32) // float32 -> float64
fmt.Printf("float32: %.2f, float64: %.2f\n", f32, f64)
// 整数和浮点数转换
var intVal int = 42
var floatVal float64 = float64(intVal) // int -> float64
var backToInt int = int(floatVal) // float64 -> int
fmt.Printf("int: %d, float64: %.1f, back to int: %d\n", intVal, floatVal, backToInt)
// 精度丢失示例
var bigFloat float64 = 3.99
var truncated int = int(bigFloat) // 截断小数部分
fmt.Printf("%.2f 转为 int: %d (小数部分被截断)\n", bigFloat, truncated)
}
go run type_conversion.go
字符串转换
package main
import (
"fmt"
"strconv"
)
func main() {
// 数字转字符串
num := 123
str1 := strconv.Itoa(num) // int -> string
str2 := strconv.FormatInt(int64(num), 10) // int64 -> string (十进制)
str3 := strconv.FormatInt(int64(num), 16) // int64 -> string (十六进制)
fmt.Printf("数字 %d 转为字符串: '%s'\n", num, str1)
fmt.Printf("十进制: '%s', 十六进制: '%s'\n", str2, str3)
// 浮点数转字符串
pi := 3.14159
floatStr := strconv.FormatFloat(pi, 'f', 2, 64)
fmt.Printf("浮点数 %.5f 转为字符串: '%s'\n", pi, floatStr)
// 字符串转数字
numStr := "456"
if converted, err := strconv.Atoi(numStr); err == nil {
fmt.Printf("字符串 '%s' 转为数字: %d\n", numStr, converted)
}
floatStr2 := "3.14"
if converted, err := strconv.ParseFloat(floatStr2, 64); err == nil {
fmt.Printf("字符串 '%s' 转为浮点数: %.2f\n", floatStr2, converted)
}
// 布尔值转换
boolStr := "true"
if converted, err := strconv.ParseBool(boolStr); err == nil {
fmt.Printf("字符串 '%s' 转为布尔值: %t\n", boolStr, converted)
}
}
go run string_conversion.go
类型断言
接口类型断言
package main
import "fmt"
func main() {
// 空接口可以存储任何类型
var value interface{} = 42
// 类型断言
if intVal, ok := value.(int); ok {
fmt.Printf("值是 int 类型: %d\n", intVal)
}
// 错误的类型断言
if strVal, ok := value.(string); ok {
fmt.Printf("值是 string 类型: %s\n", strVal)
} else {
fmt.Println("值不是 string 类型")
}
// 类型切换
checkType := func(v interface{}) {
switch val := v.(type) {
case int:
fmt.Printf("整数: %d\n", val)
case string:
fmt.Printf("字符串: %s\n", val)
case bool:
fmt.Printf("布尔值: %t\n", val)
default:
fmt.Printf("未知类型: %T\n", val)
}
}
checkType(42)
checkType("hello")
checkType(true)
checkType(3.14)
}
go run type_assertion.go
零值
各类型的零值
零值演示
package main
import "fmt"
func main() {
// 各种类型的零值
var intZero int
var floatZero float64
var boolZero bool
var stringZero string
var sliceZero []int
var mapZero map[string]int
var chanZero chan int
var funcZero func()
var ptrZero *int
var interfaceZero interface{}
fmt.Printf("int 零值: %d\n", intZero)
fmt.Printf("float64 零值: %f\n", floatZero)
fmt.Printf("bool 零值: %t\n", boolZero)
fmt.Printf("string 零值: '%s' (长度: %d)\n", stringZero, len(stringZero))
fmt.Printf("slice 零值: %v (是否为nil: %t)\n", sliceZero, sliceZero == nil)
fmt.Printf("map 零值: %v (是否为nil: %t)\n", mapZero, mapZero == nil)
fmt.Printf("channel 零值: %v (是否为nil: %t)\n", chanZero, chanZero == nil)
fmt.Printf("function 零值: %v (是否为nil: %t)\n", funcZero, funcZero == nil)
fmt.Printf("pointer 零值: %v (是否为nil: %t)\n", ptrZero, ptrZero == nil)
fmt.Printf("interface 零值: %v (是否为nil: %t)\n", interfaceZero, interfaceZero == nil)
}
go run zero_values.go
零值的实用性
package main
import "fmt"
func main() {
// 零值的实用性:可以直接使用
var counter int
counter++ // 从0开始计数
fmt.Printf("计数器: %d\n", counter)
var message string
message += "Hello" // 从空字符串开始拼接
message += ", World!"
fmt.Printf("消息: %s\n", message)
var isReady bool
if !isReady { // 默认为false
fmt.Println("还没准备好")
}
// 结构体的零值也是有用的
type Point struct {
X, Y int
}
var origin Point // 零值为 {0, 0}
fmt.Printf("原点坐标: (%d, %d)\n", origin.X, origin.Y)
}
go run zero_utility.go
常量表达式
编译时计算
常量表达式求值
package main
import "fmt"
func main() {
// 常量表达式在编译时计算
const (
a = 2
b = 3
c = a * b // 编译时计算:6
d = c * c // 编译时计算:36
e = d / 4 // 编译时计算:9
)
fmt.Printf("a = %d\n", a)
fmt.Printf("b = %d\n", b)
fmt.Printf("c = a * b = %d\n", c)
fmt.Printf("d = c * c = %d\n", d)
fmt.Printf("e = d / 4 = %d\n", e)
// 字符串常量表达式
const (
prefix = "Hello"
suffix = "World"
greeting = prefix + ", " + suffix + "!" // 编译时拼接
)
fmt.Printf("问候语: %s\n", greeting)
// 布尔常量表达式
const (
x = 10
y = 20
isXLess = x < y // 编译时计算:true
isEqual = x == y // 编译时计算:false
)
fmt.Printf("x < y: %t\n", isXLess)
fmt.Printf("x == y: %t\n", isEqual)
}
go run const_expressions.go
恭喜!你已经掌握了Go语言的基本语法。接下来让我们学习控制结构,包括条件语句、循环和函数。