设为首页 加入收藏

TOP

Go指南 - 笔记(一)
2019-03-26 16:13:28 】 浏览:307
Tags:指南 笔记

Go指南 - 笔记

标签(空格分隔): Go


Go指南

一、基础

1.包

每个Go程序都是由包构成的。

程序从main包开始运行。

包名与导入路径的最后一个元素一致

2.导入

分组导入:使用圆括号组合导入。推荐分组导入。

3.导出名

在Go中,如果一个名字以大写字母开头,那么它就是已导出的。

只能导入已导出的名字;任何未导出的名字在该包外均无法访问。

4.函数

函数可以没有参数或接受多个参数。

类型在变量名之后。

当连续两个或多个函数的已命名形参类型相同时,除最后一个外,其他的都可省略。

func add (x, y int) int {
    return x + y
}

函数可以返回多值:

func swap(x, y string) (string, string) {
    return y, x
}

func main() {
    a, b := swap("hello", "world")
}

Go的返回值可被命名,它们会被视作定义在函数顶部的变量。

没有参数的return语句返回已命名的返回值。

仅用在短函数中,否则影响代码可读性。

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

5.变量

var语句用于声明一个变量列表,类型在表达式后面。

多个连续相同的变量也可以按照函数参数一样的方式只在最后一个指定类型。

变量声明可以包含初始值,每个变量对应一个。如果初始值已存在,则可以省略类型。

var i, j int = 1, 2

只能在函数中使用:=在类型明确的地方代替var声明。

6.基本类型

bool

string

int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr

byte // uint8

rune // int32

float32 float64

complex64 complex128

intuintuintptr在32位系统上通常为32位宽,64位系统上则为64位宽。

没有明确初始值的变量声明会被赋予它们的零值:

  • 数值类型为0
  • 布尔类型为false
  • 字符串为""(空字符串)

表达式T(v)将值v转换为类型T

i := 3
f := float64(i)

7.常量

使用const关键字。不能使用:=语法。

二、流程控制语句

1.for

Go只有一种循环结构:for循环。

基本的for循环由三部分组成,它们用分号隔开:
初始化语句:在每一次迭代前执行;通常为短变量声明,该变量仅在for语句作用域中可见
条件表达式:在每次迭代前求值;一旦表达式的布尔值为false,迭代就会终止
后置语句:在每次迭代的结尾执行

for i := 0; i < 10; i++ {  }

// 初始化语句和后置语句是可选的
// 相当于while循环
j := 1
for j < 10 {  }

// 无限循环
for {  }

Go的for语句后面的三个构成部分外没有小括号,大括号{}则是必须的。

2.if

Go的if语句与for循环类似,表达式外无需小括号,而大括号{}是必须的。

if语句可以在条件表达式之前执行一个简单的语句,该语句声明变量的作用域仅在if之内(包括它的else块)。

if y := x * x; y > 100 { }

3.switch

Go会自动终止case分支,想要不终止需要fallthrough语句结束。

case可以是表达式。

switchcase语句从上到下顺次执行,直到匹配成功时停止。

switch的条件可以为true,或者说没有条件;此时相当于if else语句。

4.defer

defer语句会将函数推迟到外层函数返回之后执行。

推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用。

defer fmt.Println("world")
fmt.Println("hello")

推迟的函数调用会被压入一个栈中,当外层函数返回时,被推迟的函数会按照先进后出的顺序调用。

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

// 结果: 9 8 7 6 5 4 3 2 1 0

三、struct、slice和映射等

1.指针

Go拥有指针。指针保存了值的内存地址。
Go没有指针运算。

类型*T是指向T类型值的指针。其零值为nil

var p *int
fmt.Println(p)
// <nil>

&操作符会生成一个指向其操作数的指针。

i := 1
p = &i
fmt.Println(p)
// 0x416038

*操作符表示指针指向的底层值。这就是通常所说的“间接引用”或“重定向”。

fmt.Println(*p) // 通过指针 p 读取 i
*p = 21         // 通过指针 p 设置 i

2.结构体(struct)

一个结构体(struct)就是一组字段(field)。
结构体字段用点号来访问。

type Vertex struct {
    X int
    Y int
}

func main() {
    fmt.Printin(Vertex{1, 2}) // {1 2}
    v.X = 4
    fmt.Println(v.X) // 4
}

结构体字段可以通过结构体指针来访问。

允许隐式间接引用(不写*号):

v := Vertex{1, 2}
p := &v
fmt.Println(p.X) // 1

3.数组

类型[n]T表示拥有n个T类型的值的数组。

切片为数组元素提供动态大小的、灵活的视角。切片比数组更常用。

类型[]T表示一个元素类型为T的切片。

切片通过两个下标来界定,即一个上界和一个下界,二者以冒号分隔:

arr[low: high]

它会选择一个半开区间,包括第一个元素,排除最后一个元素。

primes := [6]int{2, 3, 5, 7, 11, 13}

var s []int = primes[1:4]
fmt.Println(s)
// [3 5 7]

切片就像数组的引用

切片并不存储任何数据,它只是描述了底层数组中的一段。
更改切片的元素会修改其底层数组中对应的元素
与它共享底层数组的切片都会观测到这些修改。

切片文法类似于没有长度的数组文法。

[]bool {true, false, true}

上面的代码会创建一个数组,然后构建了这个引用这个数组的一个切片。

下面是一个结构体切片::

s := []struct {
    i int
    b string
} {
    {1, "a"},
    {2, "b"},
    {3, "c"},
    {4, "d"},
    {5, "e"},
}

fmt.Println(s)
// [{1 a} {2 b} {3 c} {4 d} {5 e}]

在进行切片时,可以利用它的默认行为来忽略上下界。
切片下界默认值为0,上界则是该切片的长度。

对于数组:

var a [10]int

// 以下切片是等价的
a[0:10]
a[:10]
a[0:]
a[:]

切片拥有长度容量
切片的长度就是它所包含的元素的个数。
切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。
切片的零值是ni

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Go语言数组和切片的原理 下一篇Go基础(2)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目