1.map
在 Go 语言中,map 是一种内置的数据类型,用于存储键值对。它类似于其他编程语言中的哈希表或字典,是无序的集合
map的定义
// 1.未初始化的定义方式,不能直接存储数据,需要使用make函数进行初始化 var 变量名 map[键类型]值类型 // 使用make初始化示例 var scores map[string]int // 定义一个 key 为 string、value 为 int 的 map scores = make(map[string]int) // 2.直接初始化的定义方式 scores := map[string]int{ "Alice": 90, "Bob": 80, "Eve": 85, }
map的增删改查操作
// 1.添加和更新元素 scores["Alice"] = 95 // 假如已有 key 为 Alice,则修改 Alice 对应值 scores["Tom"] = 70 // 假如没有 key 为 Tom,则新增一个 key 为 Tom // 2.读取元素 fmt.Println(scores["Alice"]) // 输出 95 // 3.删除元素 delete(scores, "Tom") // 4.判断 key 是否存在,双赋值形式 value, exists := scores["Tom"] if exists { fmt.Println("Tom's score:", value) } else { fmt.Println("Tom is not in the map") }
遍历map
for key, value := range scores { fmt.Println("Key:", key, "Value:", value) }
map的长度
fmt.Println("Length of map:", len(scores))
2.函数
Go 语言中的函数是一等公民,它不仅是组织代码的基本单位,还支持许多强大的特性,例如返回多个值、匿名函数、闭包等
函数的定义
func 函数名(参数列表) 返回值列表 { 函数体 }
返回多个值的函数
package main import "fmt" // 返回两个值 func divide(a int, b int) (int, string) { if b == 0 { return 0, "Division by zero" } return a / b, "Success" } func main() { result, message := divide(10, 2) fmt.Println("Result:", result, "| Message:", message) result2, message2 := divide(10, 0) fmt.Println("Result:", result2, "| Message:", message2) }
命名返回值
在函数中,可以为返回值命名,使代码更易读,同时可以直接在函数中对返回值变量进行赋值,最后 return 即可
package main import "fmt" package main import "fmt" func swap(x, y int) (a int, b int) { a = y b = x return // 直接返回命名的返回值 } func main() { a, b := swap(3, 7) fmt.Println("After swap:", a, b) }
可变参数函数
package main import "fmt" // 计算任意数量整数的和 func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total } func main() { fmt.Println("Sum:", sum(1, 2, 3, 4)) // 输出 10 fmt.Println("Sum:", sum(10, 20, 30)) // 输出 60 }
匿名函数
// 匿名函数赋值给变量 package main import "fmt" func main() { // 将匿名函数赋值给变量 add := func(a int, b int) int { return a + b } fmt.Println("Sum:", add(3, 4)) } // 直接调用匿名函数 package main import "fmt" func main() { // 直接定义并调用匿名函数 result := func(a int, b int) int { return a * b }(4, 5) fmt.Println("Product:", result) }
闭包
闭包是一个函数,它能够访问定义在其外部作用域的变量,即使这个变量已经超出了作用域。Go 中的闭包通常用于计数器、缓存等场景
package main import "fmt" func counter() func() int { count := 0 return func() int { count++ return count } } func main() { increment := counter() fmt.Println(increment()) // 输出 1 fmt.Println(increment()) // 输出 2 fmt.Println(increment()) // 输出 3 }
函数作为参数和返回值
// 函数作为参数 package main import "fmt" func operate(a int, b int, op func(int, int) int) int { return op(a, b) } func main() { sum := func(x, y int) int { return x + y } result := operate(5, 3, sum) fmt.Println("Result:", result) } // 函数作为返回值 package main import "fmt" func multiplier(factor int) func(int) int { return func(x int) int { return x * factor } } func main() { double := multiplier(2) fmt.Println(double(5)) // 输出 10 }
延迟执行函数
defer 用于延迟执行某个函数,通常用于释放资源或关闭文件等操作。被 defer 修饰的函数会在当前函数退出前执行
package main import "fmt" func main() { fmt.Println("Start") defer fmt.Println("Deferred execution") fmt.Println("End") }
// 输出 Start End Deferred execution
内置错误处理
Go 提倡通过返回值处理错误。通常函数会返回一个值和一个错误对象,调用者需要检查错误
package main import ( "errors" "fmt" ) func divide(a, b int) (int, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil } func main() { result, err := divide(10, 0) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Result:", result) } }
3.接口
在 Go 语言中,接口(interface) 是一种抽象类型,定义了一组方法的集合。接口不关心数据的具体实现,而只关心实现者是否实现了接口中的方法。因此,接口是 Go 语言实现 多态 和 解耦 的关键机制
接口的定义
type 接口名 interface { 方法名(参数列表) 返回值列表 }
接口的实现
package main import "fmt" // 定义接口 type Speaker interface { Speak() string } // 定义结构体 type Dog struct{} type Cat struct{} // 实现接口 func (d Dog) Speak() string { return "Woof!" } func (c Cat) Speak() string { return "Meow!" } func main() { var s Speaker // Dog 实现了接口 s = Dog{} fmt.Println(s.Speak()) // 输出 "Woof!" // Cat 实现了接口 s = Cat{} fmt.Println(s.Speak()) // 输出 "Meow!" }
空接口
空接口表示任何类型都可以赋值给它,因为它不包含任何方法
package main import "fmt" func main() { var any interface{} // 空接口 any = 42 fmt.Println(any) // 输出 42 any = "Hello, Go!" fmt.Println(any) // 输出 "Hello, Go!" any = true fmt.Println(any) // 输出 true }
类型断言
在使用空接口时,可能需要断言具体类型,以便执行特定的操作
package main import "fmt" func describe(value interface{}) { // 断言具体类型 if str, ok := value.(string); ok { fmt.Println("This is a string:", str) } else if num, ok := value.(int); ok { fmt.Println("This is an integer:", num) } else { fmt.Println("Unknown type") } } func main() { describe("Hello") // 输出 This is a string: Hello describe(42) // 输出 This is an integer: 42 describe(3.14) // Unknown type }
接口嵌套
package main import "fmt" // 定义两个接口 type Reader interface { Read() string } type Writer interface { Write(data string) } // 嵌套接口 type ReaderWriter interface { Reader Writer } // 实现嵌套接口的结构体 type File struct{} func (f File) Read() string { return "Reading data from file" } func (f File) Write(data string) { fmt.Println("Writing data to file:", data) } func main() { var rw ReaderWriter = File{} fmt.Println(rw.Read()) // 调用 Read 方法 rw.Write("Hello, Go!") // 调用 Write 方法 }
接口与结构体的组合
package main import "fmt" // 定义接口 type Shape interface { Area() float64 } // 定义两个结构体 type Circle struct { radius float64 } type Rectangle struct { width, height float64 } // 实现接口方法 func (c Circle) Area() float64 { return 3.14 * c.radius * c.radius } func (r Rectangle) Area() float64 { return r.width * r.height } // 计算并打印面积 func printArea(s Shape) { fmt.Println("Area:", s.Area()) } func main() { circle := Circle{radius: 5} rectangle := Rectangle{width: 4, height: 6} printArea(circle) // 调用 Circle 的 Area 方法 printArea(rectangle) // 调用 Rectangle 的 Area 方法 }
接口零值
接口的零值是 nil,即未赋值前,接口变量默认为 nil
package main import "fmt" type Speaker interface { Speak() string } func main() { var s Speaker if s == nil { fmt.Println("s is nil") // 输出 s is nil } }
类型切换
package main import "fmt" func typeCheck(value interface{}) { switch v := value.(type) { case int: fmt.Println("Integer:", v) case string: fmt.Println("String:", v) case bool: fmt.Println("Boolean:", v) default: fmt.Println("Unknown type") } } func main() { typeCheck(42) // 输出 Integer: 42 typeCheck("Hello, Go!") // 输出 String: Hello, Go! typeCheck(true) // 输出 Boolean: true }