初始提交

This commit is contained in:
2025-08-24 01:01:26 +08:00
commit e51feb1296
35 changed files with 9348 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
/*
01-hello-world.go - Go 语言入门第一课
学习目标:
1. 了解 Go 程序的基本结构
2. 理解包package的概念
3. 学会使用 fmt 包进行输出
4. 掌握 main 函数的作用
知识点:
- package 声明
- import 导入
- main 函数
- fmt.Println 输出函数
*/
// 每个 Go 文件都必须以 package 声明开始
// main 包是特殊的包,表示这是一个可执行程序
package main
// import 用于导入其他包
// fmt 包提供了格式化输入输出的功能
import "fmt"
// main 函数是程序的入口点
// 当运行程序时,会自动执行 main 函数
func main() {
// fmt.Println 用于输出文本并自动换行
fmt.Println("Hello, World!")
fmt.Println("欢迎来到 Go 语言的世界!")
// 你也可以使用 fmt.Print不换行或 fmt.Printf格式化输出
fmt.Print("这是 ")
fmt.Print("同一行的输出\n") // \n 表示换行
// fmt.Printf 支持格式化输出,类似于 C 语言的 printf
name := "Go"
version := 1.21
fmt.Printf("我正在学习 %s 语言,版本是 %.2f\n", name, version)
// 多种输出方式的演示
demonstrateOutput()
}
// demonstrateOutput 演示不同的输出方式
func demonstrateOutput() {
fmt.Println("\n=== 输出方式演示 ===")
// 1. 基本输出
fmt.Println("1. fmt.Println - 输出并换行")
// 2. 不换行输出
fmt.Print("2. fmt.Print - ")
fmt.Print("不换行输出")
fmt.Print("\n") // 手动换行
// 3. 格式化输出
age := 25
height := 175.5
isStudent := true
fmt.Printf("3. fmt.Printf - 格式化输出:\n")
fmt.Printf(" 年龄: %d 岁\n", age) // %d 表示整数
fmt.Printf(" 身高: %.1f cm\n", height) // %.1f 表示保留1位小数的浮点数
fmt.Printf(" 是学生: %t\n", isStudent) // %t 表示布尔值
fmt.Printf(" 十六进制年龄: %x\n", age) // %x 表示十六进制
fmt.Printf(" 八进制年龄: %o\n", age) // %o 表示八进制
// 4. 通用格式符 %v
fmt.Printf("4. 通用格式符 %%v:\n")
fmt.Printf(" 年龄: %v, 身高: %v, 是学生: %v\n", age, height, isStudent)
// 5. 详细格式符 %+v 和 %#v主要用于结构体
person := struct {
Name string
Age int
}{"张三", 30}
fmt.Printf("5. 结构体输出:\n")
fmt.Printf(" %%v: %v\n", person) // 简单格式
fmt.Printf(" %%+v: %+v\n", person) // 包含字段名
fmt.Printf(" %%#v: %#v\n", person) // Go 语法格式
}
/*
运行这个程序:
1. 在终端中进入 01-basics 目录
2. 执行命令go run 01-hello-world.go
预期输出:
Hello, World!
欢迎来到 Go 语言的世界!
这是 同一行的输出
我正在学习 Go 语言,版本是 1.21
=== 输出方式演示 ===
1. fmt.Println - 输出并换行
2. fmt.Print - 不换行输出
3. fmt.Printf - 格式化输出:
年龄: 25 岁
身高: 175.5 cm
是学生: true
十六进制年龄: 19
八进制年龄: 31
4. 通用格式符 %v:
年龄: 25, 身高: 175.5, 是学生: true
5. 结构体输出:
%v: {张三 30}
%+v: {Name:张三 Age:30}
%#v: struct { Name string; Age int }{Name:"张三", Age:30}
学习要点:
1. Go 程序必须有 package 声明
2. main 包表示可执行程序
3. main 函数是程序入口
4. 使用 import 导入需要的包
5. fmt 包提供了丰富的输出功能
6. 注释使用 // 或
*/

View File

@@ -0,0 +1,258 @@
/*
02-variables.go - Go 语言变量详解
学习目标:
1. 掌握变量声明的多种方式
2. 理解 Go 的类型推断
3. 学会使用短变量声明
4. 了解变量的作用域
5. 掌握零值的概念
知识点:
- var 关键字声明
- 短变量声明 :=
- 类型推断
- 零值
- 变量作用域
- 多变量声明
*/
package main
import "fmt"
// 包级别变量声明(全局变量)
var globalVar = "我是全局变量"
var (
// 使用括号可以声明多个变量
packageVar1 = "包变量1"
packageVar2 = "包变量2"
packageVar3 int = 100
)
func main() {
fmt.Println("=== Go 语言变量详解 ===\n")
// 演示各种变量声明方式
demonstrateVariableDeclaration()
// 演示零值
demonstrateZeroValues()
// 演示类型推断
demonstrateTypeInference()
// 演示多变量声明
demonstrateMultipleDeclaration()
// 演示变量作用域
demonstrateScope()
// 演示变量赋值和修改
demonstrateAssignment()
}
// demonstrateVariableDeclaration 演示变量声明的不同方式
func demonstrateVariableDeclaration() {
fmt.Println("1. 变量声明方式:")
// 方式1: var 关键字 + 类型声明
var name string
name = "张三"
fmt.Printf(" 方式1 - var name string: %s\n", name)
// 方式2: var 关键字 + 类型声明 + 初始化
var age int = 25
fmt.Printf(" 方式2 - var age int = 25: %d\n", age)
// 方式3: var 关键字 + 类型推断
var city = "北京" // Go 会自动推断为 string 类型
fmt.Printf(" 方式3 - var city = \"北京\": %s\n", city)
// 方式4: 短变量声明(最常用)
height := 175.5 // 自动推断为 float64 类型
fmt.Printf(" 方式4 - height := 175.5: %.1f\n", height)
// 注意:短变量声明只能在函数内部使用
// 在包级别必须使用 var 关键字
fmt.Println()
}
// demonstrateZeroValues 演示 Go 的零值概念
func demonstrateZeroValues() {
fmt.Println("2. 零值演示:")
fmt.Println(" Go 中每种类型都有默认的零值")
// 声明变量但不初始化,会自动赋予零值
var intVar int
var floatVar float64
var boolVar bool
var stringVar string
var pointerVar *int
fmt.Printf(" int 零值: %d\n", intVar) // 0
fmt.Printf(" float64 零值: %f\n", floatVar) // 0.000000
fmt.Printf(" bool 零值: %t\n", boolVar) // false
fmt.Printf(" string 零值: '%s'\n", stringVar) // ""(空字符串)
fmt.Printf(" pointer 零值: %v\n", pointerVar) // <nil>
fmt.Println()
}
// demonstrateTypeInference 演示类型推断
func demonstrateTypeInference() {
fmt.Println("3. 类型推断演示:")
// Go 可以根据赋值自动推断类型
var a = 42 // 推断为 int
var b = 3.14 // 推断为 float64
var c = "Hello" // 推断为 string
var d = true // 推断为 bool
// 使用 %T 可以打印变量的类型
fmt.Printf(" a = %v, 类型: %T\n", a, a)
fmt.Printf(" b = %v, 类型: %T\n", b, b)
fmt.Printf(" c = %v, 类型: %T\n", c, c)
fmt.Printf(" d = %v, 类型: %T\n", d, d)
// 短变量声明也支持类型推断
x := 100 // int
y := 2.5 // float64
z := 'A' // rune (int32)
fmt.Printf(" x := 100, 类型: %T\n", x)
fmt.Printf(" y := 2.5, 类型: %T\n", y)
fmt.Printf(" z := 'A', 类型: %T, 值: %d\n", z, z)
fmt.Println()
}
// demonstrateMultipleDeclaration 演示多变量声明
func demonstrateMultipleDeclaration() {
fmt.Println("4. 多变量声明:")
// 方式1: 同时声明多个相同类型的变量
var x, y, z int = 1, 2, 3
fmt.Printf(" var x, y, z int = 1, 2, 3: %d, %d, %d\n", x, y, z)
// 方式2: 同时声明多个不同类型的变量
var name, age, height = "李四", 30, 180.0
fmt.Printf(" var name, age, height = ...: %s, %d, %.1f\n", name, age, height)
// 方式3: 使用短变量声明
a, b, c := "Go", 1.21, true
fmt.Printf(" a, b, c := ...: %s, %.2f, %t\n", a, b, c)
// 方式4: 使用括号组织多个变量声明
var (
firstName = "王"
lastName = "五"
fullName = firstName + lastName
)
fmt.Printf(" 组合声明: %s\n", fullName)
// 变量交换Go 的特色功能)
m, n := 10, 20
fmt.Printf(" 交换前: m=%d, n=%d\n", m, n)
m, n = n, m // 交换变量值
fmt.Printf(" 交换后: m=%d, n=%d\n", m, n)
fmt.Println()
}
// demonstrateScope 演示变量作用域
func demonstrateScope() {
fmt.Println("5. 变量作用域:")
// 访问全局变量
fmt.Printf(" 全局变量: %s\n", globalVar)
fmt.Printf(" 包变量: %s, %s, %d\n", packageVar1, packageVar2, packageVar3)
// 函数级别变量
funcVar := "函数变量"
fmt.Printf(" 函数变量: %s\n", funcVar)
// 块级别作用域
if true {
blockVar := "块变量"
fmt.Printf(" 块变量(在 if 块内): %s\n", blockVar)
// 可以访问外层变量
fmt.Printf(" 在块内访问函数变量: %s\n", funcVar)
}
// blockVar 在这里无法访问,会编译错误
// fmt.Println(blockVar) // 这行会报错
// for 循环的作用域
for i := 0; i < 3; i++ {
loopVar := fmt.Sprintf("循环变量_%d", i)
fmt.Printf(" %s\n", loopVar)
}
// i 和 loopVar 在这里都无法访问
fmt.Println()
}
// demonstrateAssignment 演示变量赋值和修改
func demonstrateAssignment() {
fmt.Println("6. 变量赋值和修改:")
// 基本赋值
var score int = 85
fmt.Printf(" 初始分数: %d\n", score)
// 修改变量值
score = 90
fmt.Printf(" 修改后分数: %d\n", score)
// 复合赋值运算符
score += 5 // 等同于 score = score + 5
fmt.Printf(" score += 5: %d\n", score)
score -= 3 // 等同于 score = score - 3
fmt.Printf(" score -= 3: %d\n", score)
score *= 2 // 等同于 score = score * 2
fmt.Printf(" score *= 2: %d\n", score)
score /= 4 // 等同于 score = score / 4
fmt.Printf(" score /= 4: %d\n", score)
score %= 10 // 等同于 score = score % 10
fmt.Printf(" score %%= 10: %d\n", score)
// 自增和自减运算符
fmt.Printf(" score++ 前: %d\n", score)
score++ // 等同于 score = score + 1
fmt.Printf(" score++ 后: %d\n", score)
score-- // 等同于 score = score - 1
fmt.Printf(" score-- 后: %d\n", score)
// 注意Go 中的 ++ 和 -- 是语句,不是表达式
// 不能写成 x = score++ 这样的形式
fmt.Println()
}
/*
运行这个程序:
go run 02-variables.go
学习要点:
1. Go 有多种变量声明方式,短变量声明 := 最常用
2. Go 支持类型推断,可以自动确定变量类型
3. 每种类型都有零值,未初始化的变量会自动赋予零值
4. 变量有作用域限制,块内变量无法在块外访问
5. Go 支持多变量同时声明和赋值
6. 复合赋值运算符可以简化代码
7. ++ 和 -- 在 Go 中是语句,不是表达式
常见错误:
1. 在包级别使用短变量声明 := (只能在函数内使用)
2. 访问超出作用域的变量
3. 将 ++ 或 -- 当作表达式使用
4. 忘记变量的零值概念
*/

View File

@@ -0,0 +1,302 @@
/*
03-constants.go - Go 语言常量详解
学习目标:
1. 理解常量的概念和作用
2. 掌握常量声明的方式
3. 学会使用 iota 枚举器
4. 了解类型化和无类型化常量
5. 掌握常量表达式的计算
知识点:
- const 关键字
- 常量组声明
- iota 枚举器
- 类型化常量 vs 无类型化常量
- 常量表达式
- 预定义常量
*/
package main
import "fmt"
// 包级别常量声明
const PI = 3.14159
const COMPANY_NAME = "Go 学习公司"
// 常量组声明
const (
// 基本常量
MAX_SIZE = 100
MIN_SIZE = 1
// 使用表达式的常量
BUFFER_SIZE = MAX_SIZE * 2
// 字符串常量
VERSION = "1.0.0"
AUTHOR = "Go 学习者"
)
// 使用 iota 的枚举常量
const (
// iota 从 0 开始,每行递增 1
MONDAY = iota // 0
TUESDAY // 1
WEDNESDAY // 2
THURSDAY // 3
FRIDAY // 4
SATURDAY // 5
SUNDAY // 6
)
// 更复杂的 iota 用法
const (
_ = iota // 0使用 _ 忽略第一个值
KB = 1 << (10 * iota) // 1 << (10 * 1) = 1024
MB // 1 << (10 * 2) = 1048576
GB // 1 << (10 * 3) = 1073741824
TB // 1 << (10 * 4) = 1099511627776
)
// 类型化常量
const (
MAX_INT int = 2147483647
MAX_FLOAT float64 = 1.7976931348623157e+308
IS_ENABLED bool = true
)
func main() {
fmt.Println("=== Go 语言常量详解 ===\n")
// 演示基本常量使用
demonstrateBasicConstants()
// 演示 iota 枚举器
demonstrateIota()
// 演示常量表达式
demonstrateConstantExpressions()
// 演示类型化和无类型化常量
demonstrateTypedConstants()
// 演示常量的特性
demonstrateConstantProperties()
}
// demonstrateBasicConstants 演示基本常量使用
func demonstrateBasicConstants() {
fmt.Println("1. 基本常量使用:")
// 使用包级别常量
fmt.Printf(" 圆周率: %f\n", PI)
fmt.Printf(" 公司名称: %s\n", COMPANY_NAME)
fmt.Printf(" 最大尺寸: %d\n", MAX_SIZE)
fmt.Printf(" 缓冲区大小: %d\n", BUFFER_SIZE)
// 函数内部常量声明
const LOCAL_CONST = "这是局部常量"
fmt.Printf(" 局部常量: %s\n", LOCAL_CONST)
// 常量组声明(函数内部)
const (
RED = "红色"
GREEN = "绿色"
BLUE = "蓝色"
)
fmt.Printf(" 颜色常量: %s, %s, %s\n", RED, GREEN, BLUE)
fmt.Println()
}
// demonstrateIota 演示 iota 枚举器
func demonstrateIota() {
fmt.Println("2. iota 枚举器:")
// 基本 iota 用法
fmt.Printf(" 星期枚举:\n")
fmt.Printf(" MONDAY: %d\n", MONDAY)
fmt.Printf(" TUESDAY: %d\n", TUESDAY)
fmt.Printf(" WEDNESDAY: %d\n", WEDNESDAY)
fmt.Printf(" THURSDAY: %d\n", THURSDAY)
fmt.Printf(" FRIDAY: %d\n", FRIDAY)
fmt.Printf(" SATURDAY: %d\n", SATURDAY)
fmt.Printf(" SUNDAY: %d\n", SUNDAY)
// 存储单位枚举
fmt.Printf(" 存储单位:\n")
fmt.Printf(" KB: %d 字节\n", KB)
fmt.Printf(" MB: %d 字节\n", MB)
fmt.Printf(" GB: %d 字节\n", GB)
fmt.Printf(" TB: %d 字节\n", TB)
// 更多 iota 示例
const (
A = iota * 2 // 0 * 2 = 0
B // 1 * 2 = 2
C // 2 * 2 = 4
D // 3 * 2 = 6
)
fmt.Printf(" iota 表达式: A=%d, B=%d, C=%d, D=%d\n", A, B, C, D)
// 跳过某些值
const (
E = iota + 1 // 0 + 1 = 1
F // 1 + 1 = 2
_ // 2 + 1 = 3 (跳过)
G // 3 + 1 = 4
)
fmt.Printf(" 跳过值: E=%d, F=%d, G=%d\n", E, F, G)
fmt.Println()
}
// demonstrateConstantExpressions 演示常量表达式
func demonstrateConstantExpressions() {
fmt.Println("3. 常量表达式:")
// 算术表达式
const (
A = 10
B = 20
SUM = A + B
PRODUCT = A * B
QUOTIENT = B / A
)
fmt.Printf(" 算术表达式:\n")
fmt.Printf(" A + B = %d\n", SUM)
fmt.Printf(" A * B = %d\n", PRODUCT)
fmt.Printf(" B / A = %d\n", QUOTIENT)
// 字符串表达式
const (
FIRST_NAME = "张"
LAST_NAME = "三"
FULL_NAME = FIRST_NAME + LAST_NAME
)
fmt.Printf(" 字符串表达式: %s\n", FULL_NAME)
// 布尔表达式
const (
X = 5
Y = 10
IS_GREATER = X > Y
IS_EQUAL = X == Y
)
fmt.Printf(" 布尔表达式:\n")
fmt.Printf(" %d > %d = %t\n", X, Y, IS_GREATER)
fmt.Printf(" %d == %d = %t\n", X, Y, IS_EQUAL)
fmt.Println()
}
// demonstrateTypedConstants 演示类型化和无类型化常量
func demonstrateTypedConstants() {
fmt.Println("4. 类型化和无类型化常量:")
// 无类型化常量(更灵活)
const UNTYPED_INT = 42
const UNTYPED_FLOAT = 3.14
const UNTYPED_STRING = "Hello"
// 类型化常量(类型固定)
const TYPED_INT int = 42
const TYPED_FLOAT float64 = 3.14
const TYPED_STRING string = "Hello"
fmt.Printf(" 无类型化常量:\n")
fmt.Printf(" UNTYPED_INT 可以赋值给不同的数值类型\n")
var i8 int8 = UNTYPED_INT // 可以
var i16 int16 = UNTYPED_INT // 可以
var i32 int32 = UNTYPED_INT // 可以
var i64 int64 = UNTYPED_INT // 可以
fmt.Printf(" int8: %d, int16: %d, int32: %d, int64: %d\n", i8, i16, i32, i64)
fmt.Printf(" 类型化常量:\n")
fmt.Printf(" TYPED_INT 只能赋值给相同类型\n")
var typedVar int = TYPED_INT // 可以,类型匹配
// var typedVar2 int32 = TYPED_INT // 编译错误,类型不匹配
fmt.Printf(" typedVar: %d\n", typedVar)
// 演示无类型化常量的精度
const HUGE = 1e1000 // 无类型化常量可以有很高的精度
fmt.Printf(" 高精度常量: 可以定义超出普通类型范围的常量\n")
fmt.Println()
}
// demonstrateConstantProperties 演示常量的特性
func demonstrateConstantProperties() {
fmt.Println("5. 常量的特性:")
// 常量在编译时确定
const COMPILE_TIME = 100 + 200
fmt.Printf(" 编译时计算: %d\n", COMPILE_TIME)
// 常量不能修改
const IMMUTABLE = "不可变"
fmt.Printf(" 不可变性: %s\n", IMMUTABLE)
// IMMUTABLE = "尝试修改" // 编译错误
// 常量可以用于数组长度
const ARRAY_SIZE = 5
var arr [ARRAY_SIZE]int
fmt.Printf(" 用作数组长度: 数组长度为 %d\n", len(arr))
// 预定义常量
fmt.Printf(" 预定义常量:\n")
fmt.Printf(" true: %t\n", true)
fmt.Printf(" false: %t\n", false)
// 常量的作用域
fmt.Printf(" 常量作用域:\n")
fmt.Printf(" 包级别常量在整个包中可见\n")
fmt.Printf(" 函数级别常量只在函数内可见\n")
// 在块作用域中定义常量
if true {
const BLOCK_CONST = "块常量"
fmt.Printf(" 块常量: %s\n", BLOCK_CONST)
}
// BLOCK_CONST 在这里不可访问
fmt.Println()
}
/*
运行这个程序:
go run 03-constants.go
学习要点:
1. 常量使用 const 关键字声明,一旦定义不能修改
2. 常量在编译时确定值,不能使用运行时才能确定的值
3. iota 是常量生成器,在 const 块中从 0 开始递增
4. 无类型化常量比类型化常量更灵活,可以赋值给兼容的类型
5. 常量可以用于需要编译时常量的地方,如数组长度
6. 常量表达式在编译时计算,支持算术、字符串、布尔运算
7. 常量有作用域限制,和变量类似
常见用途:
1. 定义配置参数(如缓冲区大小、超时时间)
2. 定义枚举值(如状态码、错误码)
3. 定义数学常数(如 PI、E
4. 定义字符串常量(如版本号、默认值)
注意事项:
1. 常量值必须在编译时确定
2. 不能将函数调用结果赋值给常量
3. 不能将变量赋值给常量
4. iota 只在 const 块中有效
*/

View File

@@ -0,0 +1,414 @@
/*
04-data-types.go - Go 语言数据类型详解
学习目标:
1. 掌握 Go 的基本数据类型
2. 理解不同数值类型的范围和用途
3. 学会字符串和字符的处理
4. 了解类型转换的方法
5. 掌握复合数据类型的基础
知识点:
- 整数类型 (int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64)
- 浮点类型 (float32, float64)
- 复数类型 (complex64, complex128)
- 布尔类型 (bool)
- 字符串类型 (string)
- 字符类型 (byte, rune)
- 类型转换
- 类型别名
*/
package main
import (
"fmt"
"math"
"unsafe"
)
func main() {
fmt.Println("=== Go 语言数据类型详解 ===\n")
// 演示整数类型
demonstrateIntegerTypes()
// 演示浮点类型
demonstrateFloatTypes()
// 演示复数类型
demonstrateComplexTypes()
// 演示布尔类型
demonstrateBooleanType()
// 演示字符串类型
demonstrateStringType()
// 演示字符类型
demonstrateCharacterTypes()
// 演示类型转换
demonstrateTypeConversion()
// 演示类型信息
demonstrateTypeInfo()
}
// demonstrateIntegerTypes 演示整数类型
func demonstrateIntegerTypes() {
fmt.Println("1. 整数类型:")
// 有符号整数
var i8 int8 = 127 // -128 到 127
var i16 int16 = 32767 // -32768 到 32767
var i32 int32 = 2147483647 // -2^31 到 2^31-1
var i64 int64 = 9223372036854775807 // -2^63 到 2^63-1
fmt.Printf(" 有符号整数:\n")
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))
// 无符号整数
var ui8 uint8 = 255 // 0 到 255
var ui16 uint16 = 65535 // 0 到 65535
var ui32 uint32 = 4294967295 // 0 到 2^32-1
var ui64 uint64 = 18446744073709551615 // 0 到 2^64-1
fmt.Printf(" 无符号整数:\n")
fmt.Printf(" uint8: %d (大小: %d 字节)\n", ui8, unsafe.Sizeof(ui8))
fmt.Printf(" uint16: %d (大小: %d 字节)\n", ui16, unsafe.Sizeof(ui16))
fmt.Printf(" uint32: %d (大小: %d 字节)\n", ui32, unsafe.Sizeof(ui32))
fmt.Printf(" uint64: %d (大小: %d 字节)\n", ui64, unsafe.Sizeof(ui64))
// 平台相关的整数类型
var i int = 2147483647 // 32位系统上是int3264位系统上是int64
var ui uint = 4294967295 // 32位系统上是uint3264位系统上是uint64
var uiptr uintptr = 0x12345678 // 存储指针的整数类型
fmt.Printf(" 平台相关类型:\n")
fmt.Printf(" int: %d (大小: %d 字节)\n", i, unsafe.Sizeof(i))
fmt.Printf(" uint: %d (大小: %d 字节)\n", ui, unsafe.Sizeof(ui))
fmt.Printf(" uintptr: 0x%x (大小: %d 字节)\n", uiptr, unsafe.Sizeof(uiptr))
// 整数的不同表示法
fmt.Printf(" 整数的不同表示法:\n")
decimal := 42 // 十进制
binary := 0b101010 // 二进制 (Go 1.13+)
octal := 0o52 // 八进制 (Go 1.13+)
hexadecimal := 0x2A // 十六进制
fmt.Printf(" 十进制: %d\n", decimal)
fmt.Printf(" 二进制: %d (0b%b)\n", binary, binary)
fmt.Printf(" 八进制: %d (0o%o)\n", octal, octal)
fmt.Printf(" 十六进制: %d (0x%X)\n", hexadecimal, hexadecimal)
fmt.Println()
}
// demonstrateFloatTypes 演示浮点类型
func demonstrateFloatTypes() {
fmt.Println("2. 浮点类型:")
// float32 和 float64
var f32 float32 = 3.14159
var f64 float64 = 3.141592653589793
fmt.Printf(" 基本浮点类型:\n")
fmt.Printf(" float32: %.7f (大小: %d 字节)\n", f32, unsafe.Sizeof(f32))
fmt.Printf(" float64: %.15f (大小: %d 字节)\n", f64, unsafe.Sizeof(f64))
// 浮点数的特殊值
fmt.Printf(" 特殊浮点值:\n")
fmt.Printf(" 正无穷: %f\n", math.Inf(1))
fmt.Printf(" 负无穷: %f\n", math.Inf(-1))
fmt.Printf(" NaN: %f\n", math.NaN())
// 浮点数的科学计数法
scientific1 := 1.23e4 // 1.23 * 10^4 = 12300
scientific2 := 1.23e-4 // 1.23 * 10^-4 = 0.000123
fmt.Printf(" 科学计数法:\n")
fmt.Printf(" 1.23e4 = %f\n", scientific1)
fmt.Printf(" 1.23e-4 = %f\n", scientific2)
// 浮点数精度问题
fmt.Printf(" 精度问题演示:\n")
var a float64 = 0.1
var b float64 = 0.2
var c float64 = 0.3
fmt.Printf(" 0.1 + 0.2 = %.17f\n", a+b)
fmt.Printf(" 0.3 = %.17f\n", c)
fmt.Printf(" 0.1 + 0.2 == 0.3: %t\n", a+b == c)
fmt.Println()
}
// demonstrateComplexTypes 演示复数类型
func demonstrateComplexTypes() {
fmt.Println("3. 复数类型:")
// complex64 和 complex128
var c64 complex64 = 3 + 4i
var c128 complex128 = 5 + 6i
fmt.Printf(" 基本复数类型:\n")
fmt.Printf(" complex64: %v (大小: %d 字节)\n", c64, unsafe.Sizeof(c64))
fmt.Printf(" complex128: %v (大小: %d 字节)\n", c128, unsafe.Sizeof(c128))
// 复数的创建方式
c1 := 1 + 2i // 直接创建
c2 := complex(3, 4) // 使用 complex 函数
c3 := complex(float64(5), 6) // 指定类型
fmt.Printf(" 复数创建方式:\n")
fmt.Printf(" 直接创建: %v\n", c1)
fmt.Printf(" complex函数: %v\n", c2)
fmt.Printf(" 指定类型: %v\n", c3)
// 复数的实部和虚部
fmt.Printf(" 复数的实部和虚部:\n")
fmt.Printf(" %v 的实部: %.1f\n", c2, real(c2))
fmt.Printf(" %v 的虚部: %.1f\n", c2, imag(c2))
// 复数运算
sum := c1 + c2
product := c1 * c2
fmt.Printf(" 复数运算:\n")
fmt.Printf(" %v + %v = %v\n", c1, c2, sum)
fmt.Printf(" %v * %v = %v\n", c1, c2, product)
fmt.Println()
}
// demonstrateBooleanType 演示布尔类型
func demonstrateBooleanType() {
fmt.Println("4. 布尔类型:")
var b1 bool = true
var b2 bool = false
var b3 bool // 零值是 false
fmt.Printf(" 基本布尔值:\n")
fmt.Printf(" b1: %t (大小: %d 字节)\n", b1, unsafe.Sizeof(b1))
fmt.Printf(" b2: %t\n", b2)
fmt.Printf(" b3 (零值): %t\n", b3)
// 布尔运算
fmt.Printf(" 布尔运算:\n")
fmt.Printf(" true && false = %t\n", true && false)
fmt.Printf(" true || false = %t\n", true || false)
fmt.Printf(" !true = %t\n", !true)
fmt.Printf(" !false = %t\n", !false)
// 比较运算产生布尔值
x, y := 10, 20
fmt.Printf(" 比较运算:\n")
fmt.Printf(" %d == %d: %t\n", x, y, x == y)
fmt.Printf(" %d != %d: %t\n", x, y, x != y)
fmt.Printf(" %d < %d: %t\n", x, y, x < y)
fmt.Printf(" %d > %d: %t\n", x, y, x > y)
fmt.Printf(" %d <= %d: %t\n", x, y, x <= y)
fmt.Printf(" %d >= %d: %t\n", x, y, x >= y)
fmt.Println()
}
// demonstrateStringType 演示字符串类型
func demonstrateStringType() {
fmt.Println("5. 字符串类型:")
var s1 string = "Hello, World!"
var s2 string = "你好,世界!"
var s3 string // 零值是空字符串 ""
fmt.Printf(" 基本字符串:\n")
fmt.Printf(" s1: \"%s\" (长度: %d, 大小: %d 字节)\n", s1, len(s1), unsafe.Sizeof(s1))
fmt.Printf(" s2: \"%s\" (长度: %d)\n", s2, len(s2))
fmt.Printf(" s3 (零值): \"%s\"\n", s3)
// 字符串是不可变的
fmt.Printf(" 字符串特性:\n")
fmt.Printf(" 字符串是不可变的immutable\n")
fmt.Printf(" 字符串是 UTF-8 编码的\n")
// 字符串操作
fmt.Printf(" 字符串操作:\n")
concatenated := s1 + " " + s2
fmt.Printf(" 连接: \"%s\"\n", concatenated)
// 原始字符串字面量
rawString := `这是一个原始字符串
可以包含换行符
和 "双引号" 以及 \n 这样的字符`
fmt.Printf(" 原始字符串:\n")
fmt.Printf(" %s\n", rawString)
// 字符串转义序列
escaped := "制表符:\t换行符:\n引号:\"反斜杠:\\"
fmt.Printf(" 转义序列:\n")
fmt.Printf(" %s\n", escaped)
// 字符串索引和切片
fmt.Printf(" 字符串索引和切片:\n")
str := "Hello"
fmt.Printf(" str[0]: %c (字节值: %d)\n", str[0], str[0])
fmt.Printf(" str[1:4]: \"%s\"\n", str[1:4])
fmt.Printf(" str[:3]: \"%s\"\n", str[:3])
fmt.Printf(" str[2:]: \"%s\"\n", str[2:])
fmt.Println()
}
// demonstrateCharacterTypes 演示字符类型
func demonstrateCharacterTypes() {
fmt.Println("6. 字符类型:")
// byte 类型uint8 的别名)
var b byte = 'A'
fmt.Printf(" byte 类型:\n")
fmt.Printf(" 字符 'A': %c (ASCII值: %d, 大小: %d 字节)\n", b, b, unsafe.Sizeof(b))
// rune 类型int32 的别名,用于 Unicode 字符)
var r1 rune = 'A'
var r2 rune = '中'
var r3 rune = '🚀'
fmt.Printf(" rune 类型:\n")
fmt.Printf(" 字符 'A': %c (Unicode值: %d, 大小: %d 字节)\n", r1, r1, unsafe.Sizeof(r1))
fmt.Printf(" 字符 '中': %c (Unicode值: %d)\n", r2, r2)
fmt.Printf(" 字符 '🚀': %c (Unicode值: %d)\n", r3, r3)
// 字符串遍历
fmt.Printf(" 字符串遍历:\n")
str := "Hello世界"
fmt.Printf(" 按字节遍历:\n")
for i := 0; i < len(str); i++ {
fmt.Printf(" [%d]: %c (%d)\n", i, str[i], str[i])
}
fmt.Printf(" 按字符遍历 (range):\n")
for i, r := range str {
fmt.Printf(" [%d]: %c (%d)\n", i, r, r)
}
// Unicode 转义
fmt.Printf(" Unicode 转义:\n")
unicode1 := '\u4e2d' // 中
unicode2 := '\U0001F680' // 🚀
fmt.Printf(" \\u4e2d: %c\n", unicode1)
fmt.Printf(" \\U0001F680: %c\n", unicode2)
fmt.Println()
}
// demonstrateTypeConversion 演示类型转换
func demonstrateTypeConversion() {
fmt.Println("7. 类型转换:")
// 数值类型转换
var i int = 42
var f float64 = float64(i) // int 转 float64
var ui uint = uint(i) // int 转 uint
fmt.Printf(" 数值类型转换:\n")
fmt.Printf(" int %d -> float64 %.1f\n", i, f)
fmt.Printf(" int %d -> uint %d\n", i, ui)
// 注意Go 不支持隐式类型转换
var i32 int32 = 100
var i64 int64 = int64(i32) // 必须显式转换
fmt.Printf(" int32 %d -> int64 %d\n", i32, i64)
// 字符串和数值转换需要使用 strconv 包
// 这里只演示字符和数值的转换
var ch byte = 65
var chStr string = string(ch)
fmt.Printf(" 字符转换:\n")
fmt.Printf(" byte %d -> string \"%s\"\n", ch, chStr)
var r rune = 20013 // '中' 的 Unicode 值
var rStr string = string(r)
fmt.Printf(" rune %d -> string \"%s\"\n", r, rStr)
// 字符串转字节切片和字符切片
str := "Hello世界"
bytes := []byte(str)
runes := []rune(str)
fmt.Printf(" 字符串转换:\n")
fmt.Printf(" string -> []byte: %v\n", bytes)
fmt.Printf(" string -> []rune: %v\n", runes)
fmt.Printf(" []byte -> string: \"%s\"\n", string(bytes))
fmt.Printf(" []rune -> string: \"%s\"\n", string(runes))
fmt.Println()
}
// demonstrateTypeInfo 演示类型信息
func demonstrateTypeInfo() {
fmt.Println("8. 类型信息:")
// 使用 %T 打印类型信息
var i int = 42
var f float64 = 3.14
var s string = "Hello"
var b bool = true
var c complex128 = 1 + 2i
fmt.Printf(" 类型信息:\n")
fmt.Printf(" %v 的类型: %T\n", i, i)
fmt.Printf(" %v 的类型: %T\n", f, f)
fmt.Printf(" \"%v\" 的类型: %T\n", s, s)
fmt.Printf(" %v 的类型: %T\n", b, b)
fmt.Printf(" %v 的类型: %T\n", c, c)
// 类型别名
type MyInt int
type MyString string
var mi MyInt = 100
var ms MyString = "自定义类型"
fmt.Printf(" 自定义类型:\n")
fmt.Printf(" %v 的类型: %T\n", mi, mi)
fmt.Printf(" \"%v\" 的类型: %T\n", ms, ms)
// 类型别名和原类型的转换
var normalInt int = int(mi) // 需要显式转换
fmt.Printf(" MyInt -> int: %d\n", normalInt)
fmt.Println()
}
/*
运行这个程序:
go run 04-data-types.go
学习要点:
1. Go 有丰富的基本数据类型,包括整数、浮点、复数、布尔、字符串
2. 整数类型有有符号和无符号之分,大小从 8 位到 64 位
3. int 和 uint 的大小取决于平台32位或64位
4. 浮点数有精度限制,比较时要注意精度问题
5. 字符串是 UTF-8 编码的,不可变的
6. byte 用于 ASCII 字符rune 用于 Unicode 字符
7. Go 不支持隐式类型转换,必须显式转换
8. 可以定义类型别名,但需要显式转换
选择类型的建议:
1. 整数:一般使用 int需要特定大小时使用 int8/16/32/64
2. 浮点:一般使用 float64性能要求高时使用 float32
3. 字符ASCII 字符用 byteUnicode 字符用 rune
4. 字符串:使用 string需要修改时转换为 []byte 或 []rune
注意事项:
1. 不同类型之间不能直接运算,必须转换为相同类型
2. 浮点数比较要考虑精度问题
3. 字符串索引访问的是字节,不是字符
4. 使用 range 遍历字符串可以正确处理 Unicode 字符
*/

View File

@@ -0,0 +1,475 @@
/*
05-operators.go - Go 语言运算符详解
学习目标:
1. 掌握算术运算符的使用
2. 理解比较运算符的规则
3. 学会逻辑运算符的应用
4. 了解位运算符的用法
5. 掌握赋值运算符的使用
6. 理解运算符的优先级
知识点:
- 算术运算符 (+, -, *, /, %, ++, --)
- 比较运算符 (==, !=, <, <=, >, >=)
- 逻辑运算符 (&&, ||, !)
- 位运算符 (&, |, ^, <<, >>)
- 赋值运算符 (=, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=)
- 其他运算符 (&, *, <-)
- 运算符优先级
*/
package main
import "fmt"
func main() {
fmt.Println("=== Go 语言运算符详解 ===\n")
// 演示算术运算符
demonstrateArithmeticOperators()
// 演示比较运算符
demonstrateComparisonOperators()
// 演示逻辑运算符
demonstrateLogicalOperators()
// 演示位运算符
demonstrateBitwiseOperators()
// 演示赋值运算符
demonstrateAssignmentOperators()
// 演示其他运算符
demonstrateOtherOperators()
// 演示运算符优先级
demonstrateOperatorPrecedence()
// 演示实际应用示例
demonstratePracticalExamples()
}
// demonstrateArithmeticOperators 演示算术运算符
func demonstrateArithmeticOperators() {
fmt.Println("1. 算术运算符:")
a, b := 15, 4
fmt.Printf(" 基本算术运算 (a=%d, b=%d):\n", a, b)
fmt.Printf(" a + b = %d + %d = %d\n", a, b, a+b)
fmt.Printf(" a - b = %d - %d = %d\n", a, b, a-b)
fmt.Printf(" a * b = %d * %d = %d\n", a, b, a*b)
fmt.Printf(" a / b = %d / %d = %d\n", a, b, a/b) // 整数除法
fmt.Printf(" a %% b = %d %% %d = %d\n", a, b, a%b) // 取余
// 浮点数除法
fa, fb := 15.0, 4.0
fmt.Printf(" 浮点数除法:\n")
fmt.Printf(" %.1f / %.1f = %.2f\n", fa, fb, fa/fb)
// 自增和自减运算符
fmt.Printf(" 自增和自减运算符:\n")
x := 10
fmt.Printf(" x = %d\n", x)
x++ // x = x + 1
fmt.Printf(" x++ 后: %d\n", x)
x-- // x = x - 1
fmt.Printf(" x-- 后: %d\n", x)
// 注意Go 中的 ++ 和 -- 是语句,不是表达式
fmt.Printf(" 注意: Go 中 ++ 和 -- 是语句,不能用在表达式中\n")
// y := x++ // 编译错误
// z := ++x // 编译错误Go 没有前置 ++
// 一元运算符
fmt.Printf(" 一元运算符:\n")
positive := +10
negative := -10
fmt.Printf(" +10 = %d\n", positive)
fmt.Printf(" -10 = %d\n", negative)
fmt.Println()
}
// demonstrateComparisonOperators 演示比较运算符
func demonstrateComparisonOperators() {
fmt.Println("2. 比较运算符:")
a, b := 10, 20
fmt.Printf(" 数值比较 (a=%d, b=%d):\n", a, b)
fmt.Printf(" a == b: %d == %d = %t\n", a, b, a == b)
fmt.Printf(" a != b: %d != %d = %t\n", a, b, a != b)
fmt.Printf(" a < b: %d < %d = %t\n", a, b, a < b)
fmt.Printf(" a <= b: %d <= %d = %t\n", a, b, a <= b)
fmt.Printf(" a > b: %d > %d = %t\n", a, b, a > b)
fmt.Printf(" a >= b: %d >= %d = %t\n", a, b, a >= b)
// 字符串比较
s1, s2 := "apple", "banana"
fmt.Printf(" 字符串比较 (s1=\"%s\", s2=\"%s\"):\n", s1, s2)
fmt.Printf(" s1 == s2: %t\n", s1 == s2)
fmt.Printf(" s1 < s2: %t (按字典序)\n", s1 < s2)
fmt.Printf(" s1 > s2: %t\n", s1 > s2)
// 布尔值比较
bool1, bool2 := true, false
fmt.Printf(" 布尔值比较:\n")
fmt.Printf(" true == false: %t\n", bool1 == bool2)
fmt.Printf(" true != false: %t\n", bool1 != bool2)
// 注意:不同类型不能直接比较
fmt.Printf(" 注意: 不同类型不能直接比较,需要类型转换\n")
var i int = 10
var f float64 = 10.0
// fmt.Println(i == f) // 编译错误
fmt.Printf(" int(10) == float64(10.0): %t\n", float64(i) == f)
fmt.Println()
}
// demonstrateLogicalOperators 演示逻辑运算符
func demonstrateLogicalOperators() {
fmt.Println("3. 逻辑运算符:")
a, b := true, false
fmt.Printf(" 基本逻辑运算 (a=%t, b=%t):\n", a, b)
fmt.Printf(" a && b: %t && %t = %t (逻辑与)\n", a, b, a && b)
fmt.Printf(" a || b: %t || %t = %t (逻辑或)\n", a, b, a || b)
fmt.Printf(" !a: !%t = %t (逻辑非)\n", a, !a)
fmt.Printf(" !b: !%t = %t\n", b, !b)
// 真值表
fmt.Printf(" 逻辑运算真值表:\n")
fmt.Printf(" A | B | A&&B | A||B | !A\n")
fmt.Printf(" ------|-------|-------|-------|------\n")
fmt.Printf(" true | true | %t | %t | %t\n", true && true, true || true, !true)
fmt.Printf(" true | false | %t| %t | %t\n", true && false, true || false, !true)
fmt.Printf(" false | true | %t| %t | %t\n", false && true, false || true, !false)
fmt.Printf(" false | false | %t| %t | %t\n", false && false, false || false, !false)
// 短路求值
fmt.Printf(" 短路求值演示:\n")
x, y := 5, 0
// && 短路:如果左边是 false右边不会执行
fmt.Printf(" 短路与: (x > 10) && (y != 0)\n")
result1 := (x > 10) && (y != 0)
fmt.Printf(" 结果: %t (右边条件不会被检查)\n", result1)
// || 短路:如果左边是 true右边不会执行
fmt.Printf(" 短路或: (x > 0) || (y != 0)\n")
result2 := (x > 0) || (y != 0)
fmt.Printf(" 结果: %t (右边条件不会被检查)\n", result2)
// 复合逻辑表达式
age := 25
hasLicense := true
hasInsurance := false
canDrive := age >= 18 && hasLicense && hasInsurance
fmt.Printf(" 复合条件判断:\n")
fmt.Printf(" 年龄: %d, 有驾照: %t, 有保险: %t\n", age, hasLicense, hasInsurance)
fmt.Printf(" 可以开车: %t\n", canDrive)
fmt.Println()
}
// demonstrateBitwiseOperators 演示位运算符
func demonstrateBitwiseOperators() {
fmt.Println("4. 位运算符:")
a, b := 12, 10 // 12 = 1100, 10 = 1010 (二进制)
fmt.Printf(" 位运算 (a=%d, b=%d):\n", a, b)
fmt.Printf(" a 的二进制: %08b\n", a)
fmt.Printf(" b 的二进制: %08b\n", b)
fmt.Printf(" a & b: %08b = %d (按位与)\n", a & b, a & b)
fmt.Printf(" a | b: %08b = %d (按位或)\n", a | b, a | b)
fmt.Printf(" a ^ b: %08b = %d (按位异或)\n", a ^ b, a ^ b)
fmt.Printf(" ^a: %08b = %d (按位取反)\n", ^a, ^a)
// 位移运算
fmt.Printf(" 位移运算:\n")
x := 8 // 1000 (二进制)
fmt.Printf(" x = %d (%08b)\n", x, x)
fmt.Printf(" x << 1: %08b = %d (左移1位)\n", x << 1, x << 1)
fmt.Printf(" x << 2: %08b = %d (左移2位)\n", x << 2, x << 2)
fmt.Printf(" x >> 1: %08b = %d (右移1位)\n", x >> 1, x >> 1)
fmt.Printf(" x >> 2: %08b = %d (右移2位)\n", x >> 2, x >> 2)
// 位运算的实际应用
fmt.Printf(" 位运算应用示例:\n")
// 检查奇偶性
num := 15
isEven := (num & 1) == 0
fmt.Printf(" %d 是偶数: %t (使用 n&1==0 检查)\n", num, isEven)
// 快速乘除法2的幂
fmt.Printf(" 快速乘除法:\n")
fmt.Printf(" %d * 4 = %d << 2 = %d\n", num, num, num << 2)
fmt.Printf(" %d / 4 = %d >> 2 = %d\n", num, num, num >> 2)
// 设置、清除、切换位
flags := 0
fmt.Printf(" 位标志操作:\n")
fmt.Printf(" 初始标志: %08b\n", flags)
flags |= (1 << 2) // 设置第2位
fmt.Printf(" 设置第2位: %08b\n", flags)
flags &^= (1 << 2) // 清除第2位
fmt.Printf(" 清除第2位: %08b\n", flags)
flags ^= (1 << 1) // 切换第1位
fmt.Printf(" 切换第1位: %08b\n", flags)
fmt.Println()
}
// demonstrateAssignmentOperators 演示赋值运算符
func demonstrateAssignmentOperators() {
fmt.Println("5. 赋值运算符:")
// 基本赋值
var x int = 10
fmt.Printf(" 基本赋值: x = %d\n", x)
// 复合赋值运算符
fmt.Printf(" 复合赋值运算符:\n")
x += 5 // x = x + 5
fmt.Printf(" x += 5: x = %d\n", x)
x -= 3 // x = x - 3
fmt.Printf(" x -= 3: x = %d\n", x)
x *= 2 // x = x * 2
fmt.Printf(" x *= 2: x = %d\n", x)
x /= 4 // x = x / 4
fmt.Printf(" x /= 4: x = %d\n", x)
x %= 3 // x = x % 3
fmt.Printf(" x %%= 3: x = %d\n", x)
// 位运算赋值
fmt.Printf(" 位运算赋值:\n")
y := 12 // 1100
fmt.Printf(" y = %d (%04b)\n", y, y)
y &= 10 // y = y & 10 (1010)
fmt.Printf(" y &= 10: y = %d (%04b)\n", y, y)
y |= 5 // y = y | 5 (0101)
fmt.Printf(" y |= 5: y = %d (%04b)\n", y, y)
y ^= 3 // y = y ^ 3 (0011)
fmt.Printf(" y ^= 3: y = %d (%04b)\n", y, y)
y <<= 1 // y = y << 1
fmt.Printf(" y <<= 1: y = %d (%04b)\n", y, y)
y >>= 2 // y = y >> 2
fmt.Printf(" y >>= 2: y = %d (%04b)\n", y, y)
// 多重赋值
fmt.Printf(" 多重赋值:\n")
a, b, c := 1, 2, 3
fmt.Printf(" a, b, c := 1, 2, 3: a=%d, b=%d, c=%d\n", a, b, c)
// 交换变量
a, b = b, a
fmt.Printf(" a, b = b, a: a=%d, b=%d (交换)\n", a, b)
fmt.Println()
}
// demonstrateOtherOperators 演示其他运算符
func demonstrateOtherOperators() {
fmt.Println("6. 其他运算符:")
// 地址运算符 &
x := 42
ptr := &x
fmt.Printf(" 地址运算符 &:\n")
fmt.Printf(" x = %d\n", x)
fmt.Printf(" &x = %p (x的地址)\n", ptr)
// 解引用运算符 *
fmt.Printf(" 解引用运算符 *:\n")
fmt.Printf(" *ptr = %d (ptr指向的值)\n", *ptr)
// 修改指针指向的值
*ptr = 100
fmt.Printf(" 修改 *ptr = 100 后, x = %d\n", x)
// 通道运算符 <- (这里只是语法演示,详细内容在并发章节)
fmt.Printf(" 通道运算符 <- (语法演示):\n")
ch := make(chan int, 1)
ch <- 42 // 发送值到通道
value := <-ch // 从通道接收值
fmt.Printf(" 通道发送和接收: %d\n", value)
fmt.Println()
}
// demonstrateOperatorPrecedence 演示运算符优先级
func demonstrateOperatorPrecedence() {
fmt.Println("7. 运算符优先级:")
// 算术运算符优先级
result1 := 2 + 3 * 4
result2 := (2 + 3) * 4
fmt.Printf(" 算术运算优先级:\n")
fmt.Printf(" 2 + 3 * 4 = %d (乘法优先)\n", result1)
fmt.Printf(" (2 + 3) * 4 = %d (括号改变优先级)\n", result2)
// 比较和逻辑运算符优先级
a, b, c := 5, 10, 15
result3 := a < b && b < c
result4 := a < b || b > c && c > a
fmt.Printf(" 比较和逻辑运算优先级:\n")
fmt.Printf(" %d < %d && %d < %d = %t\n", a, b, b, c, result3)
fmt.Printf(" %d < %d || %d > %d && %d > %d = %t\n", a, b, b, c, c, a, result4)
// 位运算符优先级
x := 6 // 110
y := 3 // 011
result5 := x & y | x ^ y
result6 := x & (y | x) ^ y
fmt.Printf(" 位运算优先级:\n")
fmt.Printf(" %d & %d | %d ^ %d = %d\n", x, y, x, y, result5)
fmt.Printf(" %d & (%d | %d) ^ %d = %d\n", x, y, x, y, result6)
// 运算符优先级表(从高到低)
fmt.Printf(" 运算符优先级表(从高到低):\n")
fmt.Printf(" 1. * / %% << >> & &^\n")
fmt.Printf(" 2. + - | ^\n")
fmt.Printf(" 3. == != < <= > >=\n")
fmt.Printf(" 4. &&\n")
fmt.Printf(" 5. ||\n")
fmt.Println()
}
// demonstratePracticalExamples 演示实际应用示例
func demonstratePracticalExamples() {
fmt.Println("8. 实际应用示例:")
// 示例1: 计算器功能
fmt.Printf(" 示例1 - 简单计算器:\n")
num1, num2 := 15.5, 4.2
operator := "+"
var result float64
switch operator {
case "+":
result = num1 + num2
case "-":
result = num1 - num2
case "*":
result = num1 * num2
case "/":
if num2 != 0 {
result = num1 / num2
} else {
fmt.Printf(" 错误: 除数不能为零\n")
return
}
}
fmt.Printf(" %.1f %s %.1f = %.2f\n", num1, operator, num2, result)
// 示例2: 判断闰年
fmt.Printf(" 示例2 - 判断闰年:\n")
year := 2024
isLeapYear := (year%4 == 0 && year%100 != 0) || (year%400 == 0)
fmt.Printf(" %d年是闰年: %t\n", year, isLeapYear)
// 示例3: 位掩码操作
fmt.Printf(" 示例3 - 权限系统 (位掩码):\n")
const (
READ = 1 << 0 // 001
WRITE = 1 << 1 // 010
EXECUTE = 1 << 2 // 100
)
// 设置权限
permissions := READ | WRITE // 011
fmt.Printf(" 初始权限: %03b (读:%t, 写:%t, 执行:%t)\n",
permissions,
permissions&READ != 0,
permissions&WRITE != 0,
permissions&EXECUTE != 0)
// 添加执行权限
permissions |= EXECUTE // 111
fmt.Printf(" 添加执行权限: %03b (读:%t, 写:%t, 执行:%t)\n",
permissions,
permissions&READ != 0,
permissions&WRITE != 0,
permissions&EXECUTE != 0)
// 移除写权限
permissions &^= WRITE // 101
fmt.Printf(" 移除写权限: %03b (读:%t, 写:%t, 执行:%t)\n",
permissions,
permissions&READ != 0,
permissions&WRITE != 0,
permissions&EXECUTE != 0)
// 示例4: 条件表达式模拟
fmt.Printf(" 示例4 - 条件表达式模拟:\n")
score := 85
var grade string
// Go 没有三元运算符,使用 if-else
if score >= 90 {
grade = "A"
} else if score >= 80 {
grade = "B"
} else if score >= 70 {
grade = "C"
} else if score >= 60 {
grade = "D"
} else {
grade = "F"
}
fmt.Printf(" 分数 %d 对应等级: %s\n", score, grade)
fmt.Println()
}
/*
运行这个程序:
go run 05-operators.go
学习要点:
1. Go 支持丰富的运算符,包括算术、比较、逻辑、位运算等
2. ++ 和 -- 在 Go 中是语句,不是表达式,不能用在赋值中
3. Go 不支持隐式类型转换,不同类型不能直接比较或运算
4. 逻辑运算符支持短路求值,可以提高效率和安全性
5. 位运算符在系统编程和性能优化中很有用
6. 复合赋值运算符可以简化代码
7. 运算符有优先级,使用括号可以改变优先级
8. Go 没有三元运算符,使用 if-else 代替
实际应用:
1. 算术运算符用于数学计算
2. 比较运算符用于条件判断
3. 逻辑运算符用于复合条件
4. 位运算符用于标志位操作、权限系统等
5. 赋值运算符用于变量更新
注意事项:
1. 除法运算要注意整数除法和浮点除法的区别
2. 取余运算的结果符号与被除数相同
3. 位运算时要注意数据类型的位数
4. 使用逻辑运算符时要注意短路求值的特性
5. 复杂表达式建议使用括号明确优先级
*/

View File

@@ -0,0 +1,23 @@
# 第一章:基础语法
本章将介绍 Go 语言的基础语法,包括程序结构、变量、常量、数据类型和运算符。
## 学习目标
- 理解 Go 程序的基本结构
- 掌握变量声明和初始化的方法
- 了解 Go 的基本数据类型
- 学会使用各种运算符
## 文件列表
- `01-hello-world.go` - Hello World 程序和基本结构
- `02-variables.go` - 变量声明和初始化
- `03-constants.go` - 常量定义和使用
- `04-data-types.go` - 基本数据类型
- `05-operators.go` - 运算符使用
## 运行示例
```bash
go run 01-hello-world.go
go run 02-variables.go
# ... 依此类推
```