青训营X豆包MarsCode技术训练营 | GO语言入门指南3

66 阅读6分钟

书再接上回: 基础语法1--->基础语法2

一起来学golang吧~A Tour of Go

基本语法(续)

流程控制

1、条件语句

在Go语言中,条件语句主要包括ifelseswitch三种类型。它们用于根据不同条件执行不同的代码块。

  1. if 语句: if语句用于根据一个表达式的结果来执行相应的代码块。如果表达式的值为true,则执行if后的代码块;如果表达式的值为false,则跳过if后的代码块。else语句用于在if条件为false时执行一个备用的代码块。
num := 10
if num > 0 {
    fmt.Println("Positive")
} else if num == 0 {
    fmt.Println("Zero")
} else {
    fmt.Println("Negative")
}
  1. switch 语句: switch 是编写一连串 if-else 语句的简便方法。它运行第一个值等于条件表达式的 case 语句。Go 的 switch 语句类似于C++、Java等其他编程语言,不过 Go 只运行选定的 case,无需break。实际上,Go 自动提供了在这些语言中每个 case 后面所需的 break 语句。除非以 fallthrough 语句结束,否则分支会自动终止。 Go 的另一点重要的不同在于 switch 的 case 无需为常量,且取值不必为整数。
day := "Sunday"
switch day {
case "Monday":
    fmt.Println("Start of the week")
case "Tuesday":
    fmt.Println("Second day")
case "Wednesday", "Thursday":
    fmt.Println("Middle of the week")
case "Friday":
    fmt.Println("End of the work week")
    fallthrough
case "Saturday", "Sunday":
    fmt.Println("Weekend")
default:
    fmt.Println("Invalid day")
}

在上面的例子中,当day为"Sunday"或者"Saturday"时,会输出下面结果,因为使用了fallthrough关键字,导致继续执行下一个case的代码块

Weekend
Invalid day

循环语句

Go 只有一种循环结构:for 循环,在循环中常常会用到 range 来遍历可迭代的数据结构。

for循环和range循环中,可以使用breakcontinue关键字来控制循环的执行流程,实现各种不同的逻辑。

普通for遍历

基本的 for 循环由三部分组成,它们用分号隔开:

  • 初始化语句:在第一次迭代前执行
  • 条件表达式:在每次迭代前求值
  • 后置语句:在每次迭代的结尾执行

初始化语句通常为一句短变量声明,该变量声明仅在 for 语句的作用域中可见。一旦条件表达式的布尔值为 false,循环迭代就会终止。

注意:和 C、Java、JavaScript 之类的语言不同,Go 的 for 语句后面的三个构成部分外没有小括号,大括号{} 则是必须的。

  1. 基本的for循环: 类似于C语言的for循环,使用for关键字和循环条件。循环条件可以是一个布尔表达式,当条件为true时循环会继续执行。
  2. for循环省略初始化和步进:for循环中,初始化和步进语句都是可选的。
  3. for循环省略全部条件: 可以将for循环的条件部分省略,相当于一个无限循环。
// 1.类似C语言的for
for i := 0; i < 5; i++ {
    fmt.Println(i)
}

// 2.省略初始化和步进
i := 0
for ; i < 5; {
    fmt.Println(i)
    i++
}

// 3.死循环
i := 0
for {
    fmt.Println(i)
    i++
    if i >= 5 {
        break
    }
}

range遍历

  1. 在循环中,常常会用到 range 来遍历可迭代的数据结构。
  2. range循环会返回两个值,一个是索引(或键),另一个是对应索引(或键)的元素值。可以使用空白标识符_来忽略其中的某个值。
  3. range循环也可以用于遍历映射的键值对。
numbers := []int{1, 2, 3, 4, 5}
// 1.range遍历数据结构
for index, value := range numbers {
    fmt.Printf("Index: %d, Value: %d\n", index, value)
}

// 2.使用空白标识符_忽略某个值
for _, value := range numbers {
    fmt.Println(value)
}

//3. 遍历映射的键值对
mymap := map[string]int{"apple": 1, "banana": 2, "orange": 3}
for key, value := range mymap {
    fmt.Printf("Key: %s, Value: %d\n", key, value)
}

函数

函数的声明和定义、调用函数

  • 使用func关键字来声明和定义一个函数。函数的声明包括函数名、参数列表和返回值。如果函数没有返回值,则可以省略返回值的部分。
  • 要调用一个函数,只需要写出函数名并传递必要的参数。如果函数有返回值,可以使用变量接收返回值
// 函数名、参数列表和返回值
func add(a, b int) int {
    return a + b
}
// 忽略返回值
func greet(name string) {
    fmt.Println("Hello, " + name)
}
// 调用函数
result := add(5, 3)
greet("Alice")

多返回值

Go语言中的函数可以返回多个值。多返回值在很多场景下非常有用,例如可以返回结果和错误,或者返回多个计算结果。

func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

result, err := divide(10, 2)
if err != nil {
    fmt.Println("Error:", err)
} else {
    fmt.Println("Result:", result)
}

匿名函数

在Go中,可以创建匿名函数(没有名字的函数),并将其分配给变量。匿名函数通常用于简短的代码块,例如作为函数参数传递或在闭包中使用。

add := func(a, b int) int {
    return a + b
}
result := add(3, 5)

变长参数

Go语言支持变长参数(可变参数),通过在参数类型前加上三个点(...)来指示。这允许函数接受任意数量的参数。

func sum(numbers ...int) int {
    total := 0
    for _, num := range numbers {
        total += num
    }
    return total
}

result := sum(1, 2, 3, 4, 5) // result = 15

函数作为参数和返回值

在Go中,函数可以作为参数传递给其他函数,也可以作为函数的返回值。

func add(a, b int) int {
    return a + b
}

func sub(a, b int) int {
    return a - b
}

func calculate(op func(int, int) int, a, b int) int {
    return op(a, b)
}

result1 := calculate(add, 5, 3) // result1 = 8
result2 := calculate(sub, 5, 3) // result2 = 2

错误处理

Go语言中的错误处理是一种机制,用于处理函数执行中可能发生的错误情况。在Go中,错误是一个接口类型(error),它通常用于表示函数是否执行成功以及错误的具体信息。

错误的定义

在Go中,error接口是一个预定义的接口,它只有一个方法。一个实现了error接口的类型可以表示一个错误。通常情况下,返回error类型的值表示函数执行失败,返回nil表示函数执行成功。

type error interface {
    Error() string
}

函数返回错误

在函数执行过程中,如果发生错误,可以通过返回error类型的值来表示错误。函数可以返回一个非nilerror值,用于指示函数执行失败,并携带错误信息。例如:多返回值的divide函数。

处理错误

在调用可能返回错误的函数时,通常需要检查错误并根据不同的错误情况采取相应的处理措施。

result, err := divide(10, 2)
if err != nil {
    fmt.Println("Error:", err)
} else {
    fmt.Println("Result:", result)
}

自定义错误

除了使用errors.New()函数创建基本的错误信息,我们还可以定义自己的错误类型,只需要实现error接口的Error()方法即可。

type MyError struct {
    message string
}

func (e *MyError) Error() string {
    return e.message
}

func doSomething() error {
    return &MyError{"Something went wrong"}
}

处理多个错误

在实际编程中,一个函数可能会返回多个错误,通常使用多个if语句或switch语句来处理不同的错误情况。

result1, err1 := doSomething()
result2, err2 := doAnotherThing()

if err1 != nil {
    fmt.Println("Error 1:", err1)
}

if err2 != nil {
    fmt.Println("Error 2:", err2)
}