jack 3 달 전
부모
커밋
446bf0e7bc
40개의 변경된 파일678개의 추가작업 그리고 0개의 파일을 삭제
  1. 8 0
      golang-learn/.idea/.gitignore
  2. 9 0
      golang-learn/.idea/golang-learn.iml
  3. 89 0
      golang-learn/.idea/inspectionProfiles/Project_Default.xml
  4. 8 0
      golang-learn/.idea/modules.xml
  5. 6 0
      golang-learn/.idea/vcs.xml
  6. 3 0
      golang-learn/26-methods/go.mod
  7. 31 0
      golang-learn/26-methods/methods.go
  8. 3 0
      golang-learn/27-interfaces/go.mod
  9. 54 0
      golang-learn/27-interfaces/interfaces.go
  10. 3 0
      golang-learn/28-type_assertions/go.mod
  11. 18 0
      golang-learn/28-type_assertions/type_assertions.go
  12. 3 0
      golang-learn/29-type_switches/go.mod
  13. 39 0
      golang-learn/29-type_switches/type_switches.go
  14. 28 0
      golang-learn/30-embedding/embedding.go
  15. 3 0
      golang-learn/30-embedding/go.mod
  16. 3 0
      golang-learn/31-goroutines/go.mod
  17. 42 0
      golang-learn/31-goroutines/goroutines.go
  18. 49 0
      golang-learn/32-channels_basics/channels_basics.go
  19. 3 0
      golang-learn/32-channels_basics/go.mod
  20. 44 0
      golang-learn/33-buffered_channels_close/buffered_channels_close.go
  21. 3 0
      golang-learn/33-buffered_channels_close/go.mod
  22. 3 0
      golang-learn/34-select_statement/go.mod
  23. 24 0
      golang-learn/34-select_statement/select_statement.go
  24. 3 0
      golang-learn/35-sync_mutex/go.mod
  25. 34 0
      golang-learn/35-sync_mutex/sync_mutex.go
  26. 3 0
      golang-learn/36-sync_waitgroup/go.mod
  27. 27 0
      golang-learn/36-sync_waitgroup/sync_waitgroup.go
  28. 6 0
      golang-learn/37-unit_tests/add.go
  29. 30 0
      golang-learn/37-unit_tests/add_test.go
  30. 3 0
      golang-learn/37-unit_tests/go.mod
  31. 0 0
      golang-learn/38-table_driven_tests/-v
  32. 6 0
      golang-learn/38-table_driven_tests/add.go
  33. 27 0
      golang-learn/38-table_driven_tests/add_test.go
  34. 3 0
      golang-learn/38-table_driven_tests/go.mod
  35. 10 0
      golang-learn/39-benchmarks/benchmarks.go
  36. 21 0
      golang-learn/39-benchmarks/benchmarks_test.go
  37. 3 0
      golang-learn/39-benchmarks/go.mod
  38. 5 0
      golang-learn/40-go_modules/go.mod
  39. 2 0
      golang-learn/40-go_modules/go.sum
  40. 19 0
      golang-learn/40-go_modules/main.go

+ 8 - 0
golang-learn/.idea/.gitignore

@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 9 - 0
golang-learn/.idea/golang-learn.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 89 - 0
golang-learn/.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,89 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="PyPackageRequirementsInspection" enabled="false" level="WARNING" enabled_by_default="false">
+      <option name="ignoredPackages">
+        <value>
+          <list size="74">
+            <item index="0" class="java.lang.String" itemvalue="blinker" />
+            <item index="1" class="java.lang.String" itemvalue="kaitaistruct" />
+            <item index="2" class="java.lang.String" itemvalue="rsa" />
+            <item index="3" class="java.lang.String" itemvalue="selenium-wire" />
+            <item index="4" class="java.lang.String" itemvalue="bs4" />
+            <item index="5" class="java.lang.String" itemvalue="canvas" />
+            <item index="6" class="java.lang.String" itemvalue="jieba" />
+            <item index="7" class="java.lang.String" itemvalue="async-timeout" />
+            <item index="8" class="java.lang.String" itemvalue="Brotli" />
+            <item index="9" class="java.lang.String" itemvalue="cryptography" />
+            <item index="10" class="java.lang.String" itemvalue="h2" />
+            <item index="11" class="java.lang.String" itemvalue="pyasn1" />
+            <item index="12" class="java.lang.String" itemvalue="zstandard" />
+            <item index="13" class="java.lang.String" itemvalue="redis" />
+            <item index="14" class="java.lang.String" itemvalue="pyOpenSSL" />
+            <item index="15" class="java.lang.String" itemvalue="charset-normalizer" />
+            <item index="16" class="java.lang.String" itemvalue="ping3" />
+            <item index="17" class="java.lang.String" itemvalue="yarl" />
+            <item index="18" class="java.lang.String" itemvalue="pycryptodome" />
+            <item index="19" class="java.lang.String" itemvalue="PyExecJS" />
+            <item index="20" class="java.lang.String" itemvalue="pyparsing" />
+            <item index="21" class="java.lang.String" itemvalue="aiosignal" />
+            <item index="22" class="java.lang.String" itemvalue="httpx" />
+            <item index="23" class="java.lang.String" itemvalue="exceptiongroup" />
+            <item index="24" class="java.lang.String" itemvalue="pymongo" />
+            <item index="25" class="java.lang.String" itemvalue="selenium" />
+            <item index="26" class="java.lang.String" itemvalue="anyio" />
+            <item index="27" class="java.lang.String" itemvalue="aiohttp" />
+            <item index="28" class="java.lang.String" itemvalue="importlib-metadata" />
+            <item index="29" class="java.lang.String" itemvalue="httpcore" />
+            <item index="30" class="java.lang.String" itemvalue="idna" />
+            <item index="31" class="java.lang.String" itemvalue="chardet" />
+            <item index="32" class="java.lang.String" itemvalue="python-stdnum" />
+            <item index="33" class="java.lang.String" itemvalue="pydot" />
+            <item index="34" class="java.lang.String" itemvalue="num2words" />
+            <item index="35" class="java.lang.String" itemvalue="python-dateutil" />
+            <item index="36" class="java.lang.String" itemvalue="pyserial" />
+            <item index="37" class="java.lang.String" itemvalue="libsass" />
+            <item index="38" class="java.lang.String" itemvalue="pyopenssl" />
+            <item index="39" class="java.lang.String" itemvalue="passlib" />
+            <item index="40" class="java.lang.String" itemvalue="zeep" />
+            <item index="41" class="java.lang.String" itemvalue="mock" />
+            <item index="42" class="java.lang.String" itemvalue="typing_extensions" />
+            <item index="43" class="java.lang.String" itemvalue="pyee" />
+            <item index="44" class="java.lang.String" itemvalue="fastapi" />
+            <item index="45" class="java.lang.String" itemvalue="starlette" />
+            <item index="46" class="java.lang.String" itemvalue="uvicorn" />
+            <item index="47" class="java.lang.String" itemvalue="websockets" />
+            <item index="48" class="java.lang.String" itemvalue="pydantic-settings" />
+            <item index="49" class="java.lang.String" itemvalue="pydantic" />
+            <item index="50" class="java.lang.String" itemvalue="alembic" />
+            <item index="51" class="java.lang.String" itemvalue="greenlet" />
+            <item index="52" class="java.lang.String" itemvalue="cairosvg" />
+            <item index="53" class="java.lang.String" itemvalue="asyncpg" />
+            <item index="54" class="java.lang.String" itemvalue="sqlalchemy-utils" />
+            <item index="55" class="java.lang.String" itemvalue="cython" />
+            <item index="56" class="java.lang.String" itemvalue="mypy" />
+            <item index="57" class="java.lang.String" itemvalue="qrcode" />
+            <item index="58" class="java.lang.String" itemvalue="black" />
+            <item index="59" class="java.lang.String" itemvalue="python-dotenv" />
+            <item index="60" class="java.lang.String" itemvalue="pypdf" />
+            <item index="61" class="java.lang.String" itemvalue="python-multipart" />
+            <item index="62" class="java.lang.String" itemvalue="xlsxwriter" />
+            <item index="63" class="java.lang.String" itemvalue="sqlalchemy" />
+            <item index="64" class="java.lang.String" itemvalue="pyicu" />
+            <item index="65" class="java.lang.String" itemvalue="svgwrite" />
+            <item index="66" class="java.lang.String" itemvalue="apscheduler" />
+            <item index="67" class="java.lang.String" itemvalue="python-jose" />
+            <item index="68" class="java.lang.String" itemvalue="asyncer" />
+            <item index="69" class="java.lang.String" itemvalue="python-barcode" />
+            <item index="70" class="java.lang.String" itemvalue="pillow" />
+            <item index="71" class="java.lang.String" itemvalue="psycopg2-binary" />
+            <item index="72" class="java.lang.String" itemvalue="helium" />
+            <item index="73" class="java.lang.String" itemvalue="pydantic_core" />
+          </list>
+        </value>
+      </option>
+    </inspection_tool>
+    <inspection_tool class="SqlDialectInspection" enabled="false" level="WARNING" enabled_by_default="false" />
+    <inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
+  </profile>
+</component>

+ 8 - 0
golang-learn/.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/golang-learn.iml" filepath="$PROJECT_DIR$/.idea/golang-learn.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
golang-learn/.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
+  </component>
+</project>

+ 3 - 0
golang-learn/26-methods/go.mod

@@ -0,0 +1,3 @@
+module methods
+
+go 1.22.2

+ 31 - 0
golang-learn/26-methods/methods.go

@@ -0,0 +1,31 @@
+package main
+
+import "fmt"
+
+// 1. 定义新类型
+type Celsius float64
+
+// 2. 实现 fmt.Stringer 接口(关键)
+func (c Celsius) String() string {
+	return fmt.Sprintf("%.1f°C", c)
+}
+
+// 3. 额外示例:指针接收者方法,可修改自身
+func (c *Celsius) Add(delta float64) {
+	*c += Celsius(delta)
+}
+
+func main() {
+	// 值类型变量
+	var roomTemp Celsius = 21
+	fmt.Println("房间温度:", roomTemp) // 自动调用 String()
+
+	// 指针类型变量
+	freezer := new(Celsius) // *Celsius
+	*freezer = -18
+	fmt.Println("冷冻室:", freezer) // 同样调用 String()
+
+	// 修改温度
+	roomTemp.Add(3)
+	fmt.Println("升温后:", roomTemp)
+}

+ 3 - 0
golang-learn/27-interfaces/go.mod

@@ -0,0 +1,3 @@
+module interfaces
+
+go 1.22.2

+ 54 - 0
golang-learn/27-interfaces/interfaces.go

@@ -0,0 +1,54 @@
+package main
+
+import (
+	"fmt"
+	"math"
+)
+
+// 1. 接口:只要实现了 Area() float64 就是 Shape
+type Shape interface {
+	Area() float64
+}
+
+// 2. 矩形
+type Rect struct {
+	W, H float64
+}
+
+// 3. 圆
+type Circle struct {
+	R float64
+}
+
+// 4. 隐式实现:Rect 有了 Area() float64 → 自动变成 Shape
+func (r Rect) Area() float64 {
+	return r.W * r.H
+}
+
+// 5. 隐式实现:Circle 同理
+func (c Circle) Area() float64 {
+	return math.Pi * c.R * c.R
+}
+
+// 6. 统一打印面积:多态
+func printArea(s Shape) {
+	fmt.Printf("面积 = %.2f\n", s.Area())
+}
+
+func main() {
+	// 7. 接口变量可以装任何实现者
+	var s Shape
+
+	s = Rect{3, 4}
+	printArea(s) // 12.00
+
+	s = Circle{R: 2}
+	printArea(s) // 12.57
+
+	// 8. 空接口:万能容器(类似 Python 的 object)
+	var box interface{}
+	box = 42
+	box = "hello"
+	box = Rect{1, 1}
+	fmt.Println("空接口里装的是:", box)
+}

+ 3 - 0
golang-learn/28-type_assertions/go.mod

@@ -0,0 +1,3 @@
+module type_assertions
+
+go 1.22.2

+ 18 - 0
golang-learn/28-type_assertions/type_assertions.go

@@ -0,0 +1,18 @@
+package main
+
+import "fmt"
+
+func sumInts(list []interface{}) int {
+	sum := 0
+	for _, v := range list {
+		if n, ok := v.(int); ok { // 关键断言
+			sum += n
+		}
+	}
+	return sum
+}
+
+func main() {
+	data := []interface{}{"a", 1, 2.5, 3, "b", 4, true}
+	fmt.Println("sum =", sumInts(data)) // 期望 1+3+4 = 8
+}

+ 3 - 0
golang-learn/29-type_switches/go.mod

@@ -0,0 +1,3 @@
+module type_switches
+
+go 1.22.2

+ 39 - 0
golang-learn/29-type_switches/type_switches.go

@@ -0,0 +1,39 @@
+package main
+
+import (
+	"fmt"
+)
+
+func printType(val interface{}) {
+	switch v := val.(type) {
+	case int:
+		fmt.Printf("Type: int, Value: %v\n", v)
+	case float64:
+		fmt.Printf("Type: float64, Value: %v\n", v)
+	case string:
+		fmt.Printf("Type: string, Value: %v\n", v)
+	case bool:
+		fmt.Printf("Type: bool, Value: %v\n", v)
+	case []int:
+		fmt.Printf("Type: []int, Value: %v\n", v)
+	case []float64:
+		fmt.Printf("Type: []float64, Value: %v\n", v)
+	case []string:
+		fmt.Printf("Type: []string, Value: %v\n", v)
+	case []bool:
+		fmt.Printf("Type: []bool, Value: %v\n", v)
+	default:
+		fmt.Printf("Type: unknown, Value: %v\n", v)
+	}
+}
+
+func main() {
+	printType(42)
+	printType(3.14)
+	printType("hello")
+	printType(true)
+	printType([]int{1, 2, 3})
+	printType(map[string]int{"a": 1, "b": 2})
+	printType(struct{ X int }{X: 99})
+	printType(nil)
+}

+ 28 - 0
golang-learn/30-embedding/embedding.go

@@ -0,0 +1,28 @@
+package main
+
+import (
+	"fmt"
+)
+
+// 定义一个结构体,它内嵌了 fmt.Stringer 接口
+type MyStruct struct {
+	Name         string
+	fmt.Stringer // 嵌入接口
+}
+
+// 实现 fmt.Stringer 接口(让 MyStruct 自己成为 Stringer)
+func (m MyStruct) String() string {
+	return fmt.Sprintf("MyStruct{Name: %s}", m.Name)
+}
+
+func main() {
+	// 创建一个 MyStruct 实例
+	ms := MyStruct{Name: "HelloKitty"}
+
+	// 调用 String() 方法(它自己实现了 fmt.Stringer)
+	fmt.Println(ms.String())
+
+	// 也可以把它当作 fmt.Stringer 使用
+	var s fmt.Stringer = ms
+	fmt.Println(s.String())
+}

+ 3 - 0
golang-learn/30-embedding/go.mod

@@ -0,0 +1,3 @@
+module embedding
+
+go 1.22.2

+ 3 - 0
golang-learn/31-goroutines/go.mod

@@ -0,0 +1,3 @@
+module goroutines
+
+go 1.22.2

+ 42 - 0
golang-learn/31-goroutines/goroutines.go

@@ -0,0 +1,42 @@
+package main
+
+import "fmt"
+
+func main() {
+	letter := make(chan struct{})
+	number := make(chan struct{})
+
+	go func() {
+		for i := 0; i < 26; i++ {
+			<-number
+			fmt.Printf("%c ", 'A'+i)
+			letter <- struct{}{}
+		}
+	}()
+
+	go func() {
+		for i := 0; i < 26; i++ {
+			<-letter
+			fmt.Printf("%d ", i)
+			number <- struct{}{}
+		}
+	}()
+
+	number <- struct{}{}
+	<-letter
+}
+
+//package main
+//
+//import "fmt"
+//
+//func main() {
+//	ch := make(chan string) // 1. 造一根管道
+//
+//	go func() { // 2. 启动一个工人(goroutine)
+//		ch <- "hello from another goroutine" //   放进管道
+//	}()
+//
+//	msg := <-ch // 3. 主工人从管道拿数据
+//	fmt.Println(msg)
+//}

+ 49 - 0
golang-learn/32-channels_basics/channels_basics.go

@@ -0,0 +1,49 @@
+package main
+
+import (
+	"fmt"
+	"sync"
+)
+
+func main() {
+	odd := make(chan struct{})  // 奇数 goroutine 的令牌
+	even := make(chan struct{}) // 偶数 goroutine 的令牌
+	done := make(chan struct{}) // 用来通知主函数结束
+	var wg sync.WaitGroup
+
+	wg.Add(2)
+
+	// 打印奇数:1,3,5,7,9
+	go func() {
+		defer wg.Done()
+		for i := 1; i <= 10; i += 2 {
+			<-odd // 等令牌
+			fmt.Println(i)
+			if i == 9 { // 最后一个奇数,不再发令牌
+				close(done)
+				return
+			}
+			even <- struct{}{} // 把令牌给偶数 goroutine
+		}
+	}()
+
+	// 打印偶数:2,4,6,8,10
+	go func() {
+		defer wg.Done()
+		for i := 2; i <= 10; i += 2 {
+			<-even // 等令牌
+			fmt.Println(i)
+			if i == 10 { // 打印完 10,直接退出
+				return
+			}
+			odd <- struct{}{} // 把令牌还给奇数 goroutine
+		}
+	}()
+
+	// 主 goroutine 先把令牌给 odd,启动交替流程
+	odd <- struct{}{}
+
+	// 等结束信号
+	<-done
+	wg.Wait()
+}

+ 3 - 0
golang-learn/32-channels_basics/go.mod

@@ -0,0 +1,3 @@
+module channels_basics
+
+go 1.22.2

+ 44 - 0
golang-learn/33-buffered_channels_close/buffered_channels_close.go

@@ -0,0 +1,44 @@
+package main
+
+import (
+	"fmt"
+	"sync"
+	"time"
+)
+
+const (
+	jobCount    = 10
+	workerCount = 3
+	bufferSize  = 5 // 缓冲通道
+)
+
+func main() {
+	jobs := make(chan int, bufferSize)
+	var wg sync.WaitGroup
+
+	// 1. 启动 worker(fan-out)
+	for w := 1; w <= workerCount; w++ {
+		wg.Add(1)
+		go worker(w, jobs, &wg)
+	}
+
+	// 2. 发送任务(主 goroutine)
+	for j := 1; j <= jobCount; j++ {
+		jobs <- j
+	}
+	close(jobs) // 关键:关闭通道,让 range 自然结束
+
+	// 3. 等待所有 worker 处理完
+	wg.Wait()
+	fmt.Println("all jobs done")
+}
+
+func worker(id int, jobs <-chan int, wg *sync.WaitGroup) {
+	defer wg.Done()
+	// range 会在通道关闭且读完剩余数据后自动退出
+	for j := range jobs {
+		fmt.Printf("worker-%d processing job-%d\n", id, j)
+		time.Sleep(300 * time.Millisecond) // 模拟耗时
+	}
+	fmt.Printf("worker-%d shutdown\n", id)
+}

+ 3 - 0
golang-learn/33-buffered_channels_close/go.mod

@@ -0,0 +1,3 @@
+module buffered_channels_close
+
+go 1.22.2

+ 3 - 0
golang-learn/34-select_statement/go.mod

@@ -0,0 +1,3 @@
+module select_statement
+
+go 1.22.2

+ 24 - 0
golang-learn/34-select_statement/select_statement.go

@@ -0,0 +1,24 @@
+package main
+
+import (
+	"fmt"
+	"time"
+)
+
+func main() {
+	ch := make(chan string)
+
+	// 模拟一个耗时 2 秒的慢任务
+	go func() {
+		time.Sleep(2 * time.Second)
+		ch <- "job done"
+	}()
+
+	// 用 select 实现 1 秒超时
+	select {
+	case res := <-ch:
+		fmt.Println("received:", res)
+	case <-time.After(1 * time.Second):
+		fmt.Println("timeout: 1s 内没有收到结果")
+	}
+}

+ 3 - 0
golang-learn/35-sync_mutex/go.mod

@@ -0,0 +1,3 @@
+module sync_mutex
+
+go 1.22.2

+ 34 - 0
golang-learn/35-sync_mutex/sync_mutex.go

@@ -0,0 +1,34 @@
+package main
+
+import (
+	"fmt"
+	"sync"
+)
+
+const (
+	goroutines = 10
+	addsPerG   = 100
+)
+
+func main() {
+	var (
+		counter int
+		mu      sync.Mutex
+		wg      sync.WaitGroup
+	)
+
+	wg.Add(goroutines)
+	for i := 0; i < goroutines; i++ {
+		go func() {
+			defer wg.Done()
+			for j := 0; j < addsPerG; j++ {
+				mu.Lock() // 进入临界区
+				counter++
+				mu.Unlock() // 离开临界区
+			}
+		}()
+	}
+
+	wg.Wait()
+	fmt.Println("final counter:", counter)
+}

+ 3 - 0
golang-learn/36-sync_waitgroup/go.mod

@@ -0,0 +1,3 @@
+module sync_waitgroup
+
+go 1.22.2

+ 27 - 0
golang-learn/36-sync_waitgroup/sync_waitgroup.go

@@ -0,0 +1,27 @@
+package main
+
+import (
+	"fmt"
+	"sync"
+	"time"
+)
+
+const N = 10 // 任务数量
+
+func main() {
+	var wg sync.WaitGroup
+
+	for i := 1; i <= N; i++ {
+		wg.Add(1) // 计数器 +1
+		go func(id int) {
+			defer wg.Done() // 任务完成时 -1
+			fmt.Printf("task %d start\n", id)
+			time.Sleep(time.Duration(id*100) * time.Millisecond) // 模拟耗时
+			fmt.Printf("task %d done\n", id)
+		}(i)
+	}
+
+	fmt.Println("main: waiting for all tasks...")
+	wg.Wait() // 阻塞直到计数器为 0
+	fmt.Println("main: all tasks completed, exit")
+}

+ 6 - 0
golang-learn/37-unit_tests/add.go

@@ -0,0 +1,6 @@
+package add
+
+// Add 被测函数:两数相加
+func Add(a, b int) int {
+	return a + b
+}

+ 30 - 0
golang-learn/37-unit_tests/add_test.go

@@ -0,0 +1,30 @@
+package add
+
+import "testing"
+
+// 测试用例 1:正数
+func TestAddPositive(t *testing.T) {
+	got := Add(2, 3)
+	want := 5
+	if got != want {
+		t.Errorf("Add(2, 3) = %d; want %d", got, want)
+	}
+}
+
+// 测试用例 2:负数
+func TestAddNegative(t *testing.T) {
+	got := Add(-1, -1)
+	want := -2
+	if got != want {
+		t.Errorf("Add(-1, -1) = %d; want %d", got, want)
+	}
+}
+
+// 测试用例 3:零值
+func TestAddZero(t *testing.T) {
+	got := Add(0, 7)
+	want := 7
+	if got != want {
+		t.Errorf("Add(0, 7) = %d; want %d", got, want)
+	}
+}

+ 3 - 0
golang-learn/37-unit_tests/go.mod

@@ -0,0 +1,3 @@
+module unit_tests
+
+go 1.22.2

+ 0 - 0
golang-learn/38-table_driven_tests/-v


+ 6 - 0
golang-learn/38-table_driven_tests/add.go

@@ -0,0 +1,6 @@
+package add
+
+// Add 被测函数:两数相加
+func Add(a, b int) int {
+	return a + b
+}

+ 27 - 0
golang-learn/38-table_driven_tests/add_test.go

@@ -0,0 +1,27 @@
+package add
+
+import "testing"
+
+func TestAdd(t *testing.T) {
+	// 1. 定义测试表:每行是 输入a, 输入b, 期望结果want
+	tests := []struct {
+		a, b, want int
+		name       string // 给用例起个可读名字,失败时好定位
+	}{
+		{2, 3, 5, "positive"},
+		{-1, -1, -2, "negative"},
+		{0, 7, 7, "zero"},
+		{0, 0, 0, "zero+zero"},
+		{-5, 5, 0, "negative+positive"},
+	}
+
+	// 2. 遍历表格,一行就是一个子测试
+	for _, tc := range tests {
+		t.Run(tc.name, func(t *testing.T) { // 子测试,失败时能看到名字
+			got := Add(tc.a, tc.b)
+			if got != tc.want {
+				t.Errorf("Add(%d, %d) = %d; want %d", tc.a, tc.b, got, tc.want)
+			}
+		})
+	}
+}

+ 3 - 0
golang-learn/38-table_driven_tests/go.mod

@@ -0,0 +1,3 @@
+module table_driven_tests
+
+go 1.22.2

+ 10 - 0
golang-learn/39-benchmarks/benchmarks.go

@@ -0,0 +1,10 @@
+package benchmarks
+
+// Sum 可变参数累加
+func Sum(nums ...int) int {
+	total := 0
+	for _, v := range nums {
+		total += v
+	}
+	return total
+}

+ 21 - 0
golang-learn/39-benchmarks/benchmarks_test.go

@@ -0,0 +1,21 @@
+package benchmarks
+
+import "testing"
+
+func BenchmarkSum10(b *testing.B)   { benchmarkSum(b, 10) }
+func BenchmarkSum100(b *testing.B)  { benchmarkSum(b, 100) }
+func BenchmarkSum1000(b *testing.B) { benchmarkSum(b, 1000) }
+
+// 通用辅助函数,避免重复代码
+func benchmarkSum(b *testing.B, size int) {
+	// 提前造好数据,防止每次循环都分配
+	nums := make([]int, size)
+	for i := 0; i < size; i++ {
+		nums[i] = i
+	}
+	b.ResetTimer() // 重置计时器,上面初始化不计入
+
+	for i := 0; i < b.N; i++ {
+		_ = Sum(nums...)
+	}
+}

+ 3 - 0
golang-learn/39-benchmarks/go.mod

@@ -0,0 +1,3 @@
+module benchmarks
+
+go 1.22.2

+ 5 - 0
golang-learn/40-go_modules/go.mod

@@ -0,0 +1,5 @@
+module hello
+
+go 1.22.2
+
+require github.com/google/uuid v1.2.0

+ 2 - 0
golang-learn/40-go_modules/go.sum

@@ -0,0 +1,2 @@
+github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
+github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=

+ 19 - 0
golang-learn/40-go_modules/main.go

@@ -0,0 +1,19 @@
+package main
+
+/*
+go mod tidy      # 清理未用依赖、补缺失
+go mod graph     # 打印依赖图
+go list -m all   # 查看最终版本集合
+go get -u        # 升级到最新次要/补丁版本
+go get -u=patch  # 只升补丁版本
+*/
+
+import (
+	"fmt"
+	"github.com/google/uuid"
+)
+
+func main() {
+	id := uuid.New() // 生成版本 4 UUID
+	fmt.Println(id.String())
+}