Compare commits

..

7 Commits

Author SHA1 Message Date
265eef5627 实现并发处理素数计算任务,添加工作协程和结果通道 2025-04-18 22:00:52 +08:00
4b77e9cfc0 键值对类型 2025-04-10 19:33:17 +08:00
199e884a55 自定义错误类型 2025-04-10 19:32:32 +08:00
3c981f9315 结构体 2025-04-10 17:45:32 +08:00
087e1ba3a1 map数据类型 2025-04-09 21:48:32 +08:00
ed6444c0ac 泛型的使用 2025-04-09 00:13:20 +08:00
6b961ce217 包内函数使用 2025-04-08 22:49:19 +08:00
9 changed files with 335 additions and 13 deletions

View File

@@ -1,22 +1,47 @@
// main包是Go程序的入口包每个可执行程序必须包含一个main包
package main
// 导入fmt包用于格式化输入输出
import "fmt"
// main函数是程序执行的入口点
func main() {
// 基本数据类型示例
// 使用var关键字声明多个变量可以分组声明
var (
integer int = 42
float float64 = 3.14
boolean bool = true
str string = "Hello"
// int类型表示整数默认是32位或64位取决于平台
integer int = 42
// float64表示64位浮点数(双精度浮点数)
float float64 = 3.14
// bool类型表示布尔值只有true或false两个值
boolean bool = true
// string类型表示字符串使用双引号包裹
str string = "Hello"
)
// 复合类型
// 复合类型示例
// array是固定长度的数组类型为[3]int表示包含3个int元素的数组
var array [3]int = [3]int{1, 2, 3}
// slice是动态数组使用:=短变量声明方式初始化
slice := []string{"a", "b", "c"}
// 打印数据类型示例
fmt.Println("数据类型示例:")
// 使用fmt.Printf格式化输出:
// %d - 整数, %f - 浮点数, %t - 布尔值, %s - 字符串
fmt.Printf("integer: %d, float: %f, boolean: %t, string: %s\n",
integer, float, boolean, str)
// %v - 通用格式,可以打印任何类型的值
fmt.Printf("array: %v, slice: %v\n", array, slice)
// map是键值对集合这里声明一个string到int的映射
var mapExample map[string]int = map[string]int{
"one": 1, // 键"one"对应值1
"two": 2, // 键"two"对应值2
}
// 从map中获取键"one"对应的值
exo := mapExample["one"]
// 打印map和从map中获取的值
fmt.Printf("mapExample: %v, mapExample[\"one\"]: %d\n", mapExample, exo)
}

View File

@@ -17,6 +17,11 @@ func swap(x, y string) (string, string) {
return y, x
}
// 完成一个两个变量值互换的函数,使用泛型
func swapGeneric[T any](x, y T) (T, T) {
return y, x
}
func main() {
// 调用无返回值函数
greet("Gopher")
@@ -28,4 +33,7 @@ func main() {
// 调用多返回值函数
a, b := swap("hello", "world")
fmt.Println(a, b)
// 调用泛型函数
x, y := swapGeneric(1, 2)
fmt.Println(x, y)
}

View File

@@ -4,6 +4,7 @@ import "fmt"
// 首字母大写的函数才能被外部包访问
func Greet(name string) {
internalFunc()
fmt.Printf("Hello, %s!\n", name)
}

View File

@@ -1,5 +1,53 @@
package main
func main() {
// TODO
import "fmt"
// 定义一个Person结构体
type Person struct {
Name string
Age int
}
// 给Person结构体定义一个方法
func (p Person) Greet() {
fmt.Printf("Hello, my name is %s and I'm %d years old.\n", p.Name, p.Age)
}
// 嵌套结构体示例
type Employee struct {
Person
JobTitle string
}
func main() {
// 结构体初始化方式1字段顺序
p1 := Person{"Alice", 25}
// 结构体初始化方式2字段名指定
p2 := Person{
Name: "Bob",
Age: 30,
}
// 访问结构体字段
fmt.Println(p1.Name) // Alice
fmt.Println(p2.Age) // 30
// 调用结构体方法
p1.Greet() // Hello, my name is Alice and I'm 25 years old.
p2.Greet() // Hello, my name is Bob and I'm 30 years old.
// 嵌套结构体初始化
emp := Employee{
Person: Person{
Name: "Charlie",
Age: 35,
},
JobTitle: "Developer",
}
// 访问嵌套结构体字段
fmt.Println(emp.Name) // Charlie (提升字段)
fmt.Println(emp.JobTitle) // Developer
emp.Greet() // Hello, my name is Charlie and I'm 35 years old.
}

View File

@@ -1,5 +1,61 @@
package main
func main() {
// TODO
import "fmt"
// 定义一个接口
type Shape interface {
Area() float64
}
// 定义一个结构体Rectangle
type Rectangle struct {
Width, Height float64
}
// 实现接口方法Area
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// 定义另一个结构体Circle
type Circle struct {
Radius float64
}
// 实现接口方法Area
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
func main() {
// 创建接口类型的切片
shapes := []Shape{
Rectangle{Width: 10, Height: 5},
Circle{Radius: 7},
}
shapes2 := []Shape{
Rectangle{Width: 20, Height: 10},
Circle{Radius: 14},
Rectangle{Width: 30, Height: 15},
Rectangle{5, 5},
}
// 遍历并调用接口方法
for _, shape := range shapes {
fmt.Printf("Shape Area: %.2f\n", shape.Area())
}
// i := 0
// for {
// fmt.Printf("Shape Area: %.2f\n", shapes2[i].Area())
// i++
// if i >= len(shapes2) {
// break
// }
// }
for _, shape := range shapes2 {
fmt.Printf("%.2f\n", shape.Area())
}
}

View File

@@ -1,5 +1,107 @@
package main
func main() {
// TODO
import (
"errors" // 提供基本错误处理功能
"fmt" // 用于格式化输出
"os" // 提供操作系统功能
"strconv" // 用于字符串转换
)
// DivisionError 是一个自定义错误类型
// 它包含除法运算的被除数、除数和错误信息
type DivisionError struct {
dividend float64 // 被除数
divisor float64 // 除数
message string // 错误信息
}
// Error 方法实现了 error 接口
// 这使得 DivisionError 可以作为一个错误类型使用
func (e *DivisionError) Error() string {
return fmt.Sprintf("%s: %f / %f", e.message, e.dividend, e.divisor)
}
// divide 函数执行除法运算,并处理除数为零的情况
// 参数:
// - dividend: 被除数
// - divisor: 除数
//
// 返回:
// - float64: 除法结果
// - error: 可能的错误
func divide(dividend, divisor float64) (float64, error) {
if divisor == 0 {
// 当除数为零时,返回自定义错误
return 0, &DivisionError{
dividend: dividend,
divisor: divisor,
message: "cannot divide by zero",
}
}
return dividend / divisor, nil
}
// readConfig 函数读取配置文件并演示错误包装
// 使用 fmt.Errorf 和 %w 来包装底层错误
func readConfig(filename string) (string, error) {
data, err := os.ReadFile(filename)
if err != nil {
// 使用 %w 包装原始错误,保留错误链
return "", fmt.Errorf("failed to read config file: %w", err)
}
return string(data), nil
}
// parseAge 函数解析年龄字符串,展示多重错误处理
// 包含多个验证步骤,每步都可能产生不同的错误
func parseAge(age string) (int, error) {
// 检查空字符串
if age == "" {
return 0, errors.New("age cannot be empty")
}
// 将字符串转换为整数
n, err := strconv.Atoi(age)
if err != nil {
// 包装转换错误
return 0, fmt.Errorf("invalid age format: %w", err)
}
// 验证年龄范围
if n < 0 || n > 150 {
return 0, fmt.Errorf("age %d is out of valid range (0-150)", n)
}
return n, nil
}
func main() {
// 示例1演示自定义错误的使用
result, err := divide(10, 0)
if err != nil {
fmt.Printf("Division error: %v\n", err)
} else {
fmt.Printf("Result: %f\n", result)
}
// 示例2演示错误包装和错误类型断言
_, err = readConfig("nonexistent.txt")
if err != nil {
fmt.Printf("Config error: %v\n", err)
// 使用 os.IsNotExist 判断具体的错误类型
if os.IsNotExist(err) {
fmt.Println("The file does not exist")
}
}
// 示例3演示多重错误处理
ages := []string{"25", "-5", "abc", "200", ""}
for _, age := range ages {
parsedAge, err := parseAge(age)
if err != nil {
fmt.Printf("Error parsing age '%s': %v\n", age, err)
continue
}
fmt.Printf("Valid age: %d\n", parsedAge)
}
}

View File

@@ -1,5 +1,28 @@
package main
func main() {
// TODO
import (
"fmt"
"time"
)
// 模拟一个耗时的计算任务
func heavyTask(id int) {
fmt.Printf("任务 %d 开始执行\n", id)
time.Sleep(2 * time.Second)
fmt.Printf("任务 %d 执行完成\n", id)
}
func main() {
fmt.Println("程序开始...")
// 启动200个goroutine
for i := 1; i <= 200; i++ {
go heavyTask(i)
}
// 主线程等待一段时间确保goroutine有足够时间执行
// 注意:在实际生产环境中应该使用更好的同步机制
time.Sleep(3 * time.Second)
fmt.Println("程序结束...")
}

View File

@@ -0,0 +1,3 @@
module morecon
go 1.24.1

View File

@@ -0,0 +1,56 @@
package main
import (
"fmt"
"math"
)
// 判断一个数是否为素数
func isPrime(n int) bool {
if n <= 1 {
return false
}
sqrt := int(math.Sqrt(float64(n)))
for i := 2; i <= sqrt; i++ {
if n%i == 0 {
return false
}
}
return true
}
func worker(id int, jobs <-chan int, results chan<- int) {
for job := range jobs {
fmt.Printf("Worker %d processing job %d\n", id, job)
// 计算从job开始的前100个数中有多少个素数
count := 0
for i := job; i < job+100; i++ {
if isPrime(i) {
count++
}
}
results <- count // 将结果发送到results通道
}
}
func main() {
jobs := make(chan int, 100) // 工作通道
results := make(chan int, 100) // 结果通道
// 启动3个工作协程
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// 发送工作任务
for j := 1; j <= 80; j++ {
jobs <- j
}
close(jobs)
// 收集结果
for i := 1; i <= 80; i++ {
result := <-results
fmt.Printf("Got result: %d\n", result) // 输出每个范围内的素数个数
}
}