GoLang基础语法学习(一) | 豆包MarsCode AI刷题

87 阅读6分钟

Go语言(又称Golang)是Google在2009年发布的一种静态类型、编译型编程语言。它设计的初衷是为了提高编程效率,同时保持简洁性。Go语言具有高效的并发支持、垃圾回收机制以及强大的标准库,这使得它在开发网络服务、数据处理等应用中非常流行。Go语言是一个值得深入学习的语言,它不仅能够帮助开发者快速构建应用程序,而且其背后的理念和技术也是现代软件工程不可或缺的一部分。通过掌握Go的基础语法和进阶概念,开发者可以在多种场景下灵活运用Go,构建高效、可靠的系统。

基础语法

变量声明

在Go中,变量声明有多种方式。最常见的是使用var关键字声明变量。这种方式显式地指定了变量的类型和初始值。除了上述方式,还可以使用简短声明形式:=,这种形式会根据赋值自动推断变量的类型。这种方式在编写代码时更加简洁,但需要注意的是,:=只能在函数内部使用。

package main

import "fmt"

func main() {
    var a int = 10 // 显式类型声明
    b := 20        // 类型推断
    fmt.Println(a, b)
}

常量是在编译时期确定其值的标识符,使用const关键字声明。常量可以是数值、字符串、布尔值等;常量在程序运行期间是不可变的,适用于那些需要固定值的场景,如数学常数、配置参数等。

const Pi = 3.1415926
const MaxNum = 1000

数据类型

Go语言提供了丰富的基本数据类型,包括但不限于整型、浮点型、布尔型和字符串等;此外,Go还支持复合类型,如数组、切片、映射和结构体等。这些类型可以用于更复杂的数据结构和逻辑处理。

控制语句(if、switch、循环)

Go语言中的控制结构与C语言类似,包括if语句、switch语句和循环语句等。

func main() {
    num := 10
    if num > 0 {
        fmt.Println("正")
    } else if num < 0 {
        fmt.Println("负")
    } else {
        fmt.Println("零")
    }

    switch day := time.Now().Weekday(); day {
    case time.Saturday, time.Sunday:
        fmt.Println("周日")
    default:
        fmt.Println("工作日")
    }

    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }

    for {
        fmt.Println("无限循环")
        break // 使用break退出循环
    }
}

函数

基本函数定义

无参数无返回值的函数

最基本的函数定义形式是没有参数和返回值的函数。这种函数通常用于执行一些简单的任务,如打印消息或执行一系列操作。

带参数的函数

函数可以接受一个或多个参数,参数类型需要在函数定义中明确指定。参数允许函数接收外部输入,从而实现更灵活的功能。

带返回值的函数

函数可以返回一个或多个值。返回值的类型也需要在函数定义中明确指定。返回值使得函数可以将计算结果传递给调用者,从而实现数据的传递和处理。

多返回值

Go语言支持函数返回多个值,这在处理错误时非常有用。多返回值使得函数可以同时返回正常结果和错误信息,提高了错误处理的灵活性和安全性。

可变参数函数

Go语言支持可变参数函数,即函数可以接受不定数量的参数。使用 ... 关键字来定义可变参数。可变参数函数在处理不确定数量的输入时非常方便,如计算多个数的总和。

匿名函数

匿名函数是没有名字的函数,可以在定义后立即执行,也可以作为值传递。匿名函数在需要临时定义和执行函数的场景中非常有用,如回调函数和即时计算。

闭包

闭包是一个函数值,它可以引用其包含作用域中的变量。闭包在处理回调和延迟执行时非常有用。闭包可以捕获并保留外部变量的状态,从而实现更复杂的逻辑。

变量作用域

在Go语言中,变量的作用域分为局部变量和全局变量。

  • 局部变量:在函数内部定义的变量,只在该函数内部可见。
  • 全局变量:在函数外部定义的变量,可以在整个包内可见。

局部变量通常用于函数内部的临时存储,而全局变量用于在整个包内共享数据。

函数作为参数和返回值

Go语言允许函数作为参数传递,也可以作为函数的返回值。函数作为参数传递使得函数可以接受其他函数作为输入,从而实现更灵活的函数组合和高阶函数。函数作为返回值使得函数可以返回其他函数,从而实现更复杂的逻辑和动态行为。

汇总代码

以下是一个综合示例,展示了上述各种函数特性的使用:

package main

import (
    "errors"
    "fmt"
)

// 无参数无返回值的函数
func sayHello() {
    fmt.Println("Hello, Go!")
}

// 带参数的函数
func greet(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

// 带返回值的函数
func add(a, b int) int {
    return a + b
}

// 多返回值的函数
func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("除数不能为零")
    }
    return a / b, nil
}

// 可变参数函数
func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}

// 匿名函数
func useAnonymousFunction() {
    // 定义并立即执行匿名函数
    func() {
        fmt.Println("这是一个匿名函数")
    }()

    // 将匿名函数赋值给变量
    add := func(a, b int) int {
        return a + b
    }
    result := add(5, 3)
    fmt.Println("结果:", result)
}

// 闭包
func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

// 变量作用域
var globalVar int = 10 // 全局变量

func main() {
    sayHello()
    greet("Alice")

    result := add(5, 3)
    fmt.Println("加法结果:", result)

    result, err := divide(10, 2)
    if err != nil {
        fmt.Println("错误:", err)
    } else {
        fmt.Println("除法结果:", result)
    }

    total := sum(1, 2, 3, 4, 5)
    fmt.Println("总和:", total)

    useAnonymousFunction()

    nextCount := counter()
    fmt.Println(nextCount()) // 输出 1
    fmt.Println(nextCount()) // 输出 2
    fmt.Println(nextCount()) // 输出 3

    localVar := 20 // 局部变量
    fmt.Println("全局变量:", globalVar)
    fmt.Println("局部变量:", localVar)
}

数组与切片

数组是固定长度的数据集合,而切片则是一个可以动态调整大小的数组视图;切片的灵活性使其在实际开发中非常常用,尤其是在处理动态数据集合时。

// 数组
var arr [5]int = [5]int{1, 2, 3, 4, 5}

// 切片
slice := []int{1, 2, 3, 4, 5}
slice = append(slice, 6) // 添加元素

// 打印切片
fmt.Println(slice)

map

map是键值对的集合,用于存储非连续、无序的数据:

func main() {
    m := make(map[string]int)
    m["apple"] = 1
    m["banana"] = 2

    fmt.Println(m["apple"]) // 输出 1

    // 检查键是否存在
    value, exists := m["orange"]
    if exists {
        fmt.Println(value)
    } else {
        fmt.Println("键不存在")
    }
}

结构体

结构体(struct)是Go语言中用于定义复杂数据类型的工具,可以包含多个不同类型的字段:

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    fmt.Println(p.Name, p.Age)

    // 修改结构体字段
    p.Age = 31
    fmt.Println(p.Age)
}