【Go语言】 基础

变量的省略定义

// 型は自動で推測される
name := "John"

// 以下と同じ
var name string
name = "John"

具有名称的返回值

通过将返回值定义为变量,可以仅通过return语句来返回。

func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return
}

func main() {
	a, b := swap(10, 7)
	fmt.Println(a, b)
}

推迟

将传递给defer的函数的执行延迟到调用者函数结束(返回)。
如果有多个传递给defer的函数,则这些调用将以堆栈(stack)方式存储。当调用者函数返回时,defer传递的函数将按照LIFO(后进先出)的顺序执行。

func main() {
	defer fmt.Println("world")
	fmt.Println("hello")
}
// 結果
// hello
// world

func main() {
	fmt.Println("counting")
	for i := 0; i < 10; i++ {
		defer fmt.Println(i)
	}
	fmt.Println("done")
}
// 結果
// counting
// done
// 9```
// 8
// .
// .
// 0

切片

切片类似于对数组的引用。
切片不存储任何数据,仅指示原始数组的子序列。
当修改切片的元素时,对应的原始数组元素也会被修改。
共享同一个原始数组的其他切片将反映这些更改。

func main() {
	names := [4]string{
		"John",
		"Paul",
		"George",
		"Ringo",
	}
	fmt.Println(names)

	a := names[0:2]
	b := names[1:3]
	fmt.Println(a, b)

	b[0] = "XXX"
	fmt.Println(a, b)
	fmt.Println(names)
}

// 結果
// [John Paul George Ringo]
// [John Paul] [Paul George]
// [John XXX] [XXX George]
// [John XXX George Ringo]
イメージ
s = []int{10, 20, 30, 40, 50, 60}
// start_index >= 2 ~ end_index < 4 までの要素
s1 := s[1:4]  //=> [20, ]

创建函数

// Make関数
// 第1引数:スライスの型
// 第2引数:スライスの長さ
// 第3引数:スライスの容量

// 長さ5 要素int型のスライス作成
a := make([]int, 5)
==> [0, 0, 0, 0, 0] //結果 要素は全てゼロ値(int型の場合は0)で初期化される

// 長さ0 容量5 要素int型のスライス作成
// 将来的に最大で5つの要素を格納できる
b := make([]int, 0, 5)
==> [] //長さ0なので要素なし

循环

当使用range在切片上进行循环时,range会在每次迭代中返回两个变量。第一个变量是索引(index),第二个变量是索引位置上元素的副本。

func main() {
	for i, v := range pow {
		fmt.Printf("2**%d = %d\n", i, v)
	}
}

地图

// key:int value:文字列 とするマップを作成
e := make(map[int]string)
e[1] = "1st"  // 追加
e[2] = "2nd"
e[3] = "3rd"
fmt.Println(e)
delete(e, 2)  // 削除
fmt.Println(e)

// 存在確認
elem, ok := e[1]
fmt.Println("The value:", elem, "Present?", ok)

// 結果
// map[1:1st 2:2nd 3:3rd]
// map[1:1st 3:3rd]
// The value:  Present? false

闭包

闭包是引用外部作用域中变量,并保持和利用该变量的函数。在Golang中,可以使用匿名函数(函数字面量)来创建闭包。匿名函数以 `func() …` 的形式表示,并通过将其作为函数类型的返回值来实现闭包功能。

package main
import "fmt"

// クロージャを返す関数
func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

// count変数の値を取得する関数
func getCount() int {
    return counter()()
}

func main() {
    increment := counter()

    fmt.Println(increment()) // クロージャを呼び出して countの値を更新。1が出力される
    fmt.Println(increment()) // クロージャを呼び出して、countの値を更新。2が出力される

    fmt.Println(getCount())  // countの現在の値を取得する(クロージャの再生成はしない)2が出力される
}

在这段代码中,counter()函数返回了一个闭包。counter()函数内部定义了一个count变量,并且这个变量被包含在闭包中。闭包可以访问count变量并更新其值。

increment变量持有调用counter()函数并返回结果的闭包。每次调用闭包时,count变量会更新并返回新的值。