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
}

By Liu

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注