go语言基础(一)|青训营笔记

80 阅读3分钟

变量/常量

go语言的变量声明主要有两种形式,一种是通过var声明(常量也可通过const声明),如下所示:

var t bool //= true,省略后面的赋值时,变量会赋予默认值

//可单个声明,可分组为语法块
const (
    x int = 12
    f float32 = 1.2
    s string = "hello"
)

注意当声明省略了基本类型的时候,会根据赋值进行类型推导

var i = 64 //int

还有一种是短变量声明,通过:=在类型明确的地方代替var,这里也用到了类型推导(const无法这样声明)

i := 12 //int
f := 12.3 //float64
c := 12 + 3i //complex128

类型转换的方法为T(v),例如f := float64(i)

流程控制语句

for

for有三种形式的循环

var sum int = 1
//形式一,有三个条件,与Java的形式区别不大
for i := 1; i < 10; i++ {
    sum += i
}
//形式二,有一个条件,类似于Java中的while
for sum < 100 {
    sum += sum
}
//形式三,没有条件,是一个无限循环
for {
    sum += 1
}

if

if有两种形式

var x int = -3
//形式一,类似于Java中的if
if x < 0 {
    x = -x
}
//形式二,在条件表达式前执行一个简单的语句,语句的变量作用域只在if/else内
if i := 3; i > 0 {
    i = -i
} else {
    //...
}

defer

defer会将后面跟的函数推迟到外层函数返回之后执行

注意事项:

  1. 推迟调用的函数会立即求值,最后被调用
  2. 被推迟的函数被压入一个栈中,故被调用的顺序为后进先出
fmt.Println("counting")
for i := 0; i < 3; i++ {
    defer fmt.Println(i)
}
fmt.Println("done")
/* 结果为
counting
done
2
1
0
*/

更多类型

指针

指针和C++类似

var x int = 13
var y *int = &x
fmt.Println(*y)

结构体

一组字段

type Vertex struct {
    X int
    Y int
}

v := Vertex{1, 2}
v := Vertex{X: 1} //结构体文法,未初始化的字段会隐式初始化

结构体指针可以直接通过隐式间接引用(同结构体直接访问字段,如p.X

数组/切片

注意数组是固定数量

var a [10]int

想要提供动态大小,就需要切片,切片类似于数组的引用,不存储任何数据,引用了底层的数组,切片有两种声明方式

primes := [6]int{1, 2, 3, 4, 5, 6}
var s1 []int = primes[:4] //方法一,通过数组切片获得
var s2 []int = {1, 2, 3, 4} //方法二,构建一个数组,同时构建一个引用他得切片
var s3 []int = make([]int, 4[, 5]) //方法三,通过make创建len(s3) = 4, cap(s3) = 5

通过func append(s []T, vs ..T) []T向切片追加元素

var s []int
s = append(s, 0)
s = append(s, 1, 2, 3, 4)

range

for循环的range形式可遍历切片映射

var pow = []int{1, 2, 3, 4}
for i, v := range pow {
    fmt.Printf("index is %v, value is %v\n", i, v)
}
//单独获取索引
for i := range pow { 
    fmt.Printf("index is %v\n", i)
}

映射

映射就是map,将键映射到值,有两种声明方式

var m map[string]int = make(map[string]int) //方式一,通过make创建
var m map[string]int = map[string]int{
    "helllo": 1,
    "world": 2
} //方式二,文法方式,可创建空映射

修改映射

//修改或添加元素
m[key] = elem
//获得元素
elem = m[key]
elem, ok = m[key]
//删除元素
delete(m, key)

函数闭包

我个人的理解是,一个函数(如func1)的返回值也是一个函数(如func2),同时返回的函数中(func2)引用了了外边函数定义的变量,例:

//内部返回的函数使用了left和right
func fibonacci() func() int {
	left := 0
	right := 1
	return func() int {
		cur := left
		left = right
		right += cur
		return cur
	}
}

func main() {
	f := fibonacci()
    //闭包使用过程中会改变所引用的变量,从而导致结果的不同
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}