前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Go语言入门经典》4~6章读书笔记

《Go语言入门经典》4~6章读书笔记

作者头像
跑马溜溜的球
发布2020-12-07 14:49:51
6510
发布2020-12-07 14:49:51
举报
文章被收录于专栏:日积月累1024

第4章 函数

4.1 函数是什么

4.1.2 返回单个值

代码语言:javascript
复制
func isEven(i int) bool{
    return i % 2 == 0;
}

4.1.3 返回多个值

在Go语言中,可在函数签名中声明多个返回值,让函数返回多个结果。在这种情况下,终止语句可返回多个值。

代码语言:javascript
复制
func getPrize()(int, string){
    i := 2
    s := "goldfish"
    
    return i,s
}

调用这个函数时,可直接将返回值赋给变量并使用它们。

代码语言:javascript
复制
func main() {
    num, prize := getPrize();
    fmt.Println(num, prize)
}

4.2 定义不定参数函数

不定参数函数是参数数量不确定的函数。通俗地说,这意味着它们接受可变数量的参数。在Go语言中,能够传递可变数量的参数,但它们的类型必须与函数签名指定的类型相同。要指定不定参数,可使用3个点(…)。

在下面的示例中,函数签名指定函数可接受任意数量的int参数。

代码语言:javascript
复制
func sumNum(nums...int) int{
}

4.3 使用具名返回值

具名返回值让函数能够在返回前将值赋给具名变量,这有助于提升函数的可读性,使其功能更加明确。要使用具名返回值,可在函数签名的返回值部分指定变量名。

代码语言:javascript
复制
package main

import (
    "fmt"
)

func sayHi()(x string, y string){
    x = "hello"
    y = "world"
    return;
}

func main() {
    str1, str2 := sayHi();
    fmt.Println(str1)
    fmt.Println(str2)
}

4.4 使用递归函数

要在函数中实现递归,可将调用自己的代码作为终止语句中的返回值。

4.5 将函数作为值传递

Go将函数视为一种类型,因此可将函数赋给变量,以后再通过变量来调用它们。

代码语言:javascript
复制
package main

import (
    "fmt"
    "reflect"
)

func anotherFunction(f func() string) string{
    return f();
}

func main() {
    fn := func() string{
        return "function called"
    }

    fmt.Println(reflect.TypeOf(fn));
    fmt.Println(anotherFunction(fn));
}

结果如下

代码语言:javascript
复制
func() string
function called

函数anotherFunction的签名中包含一个子函数签名,这表明这个参数是一个返回字符串的函数。

第5章控制流程

5.2 使用else语句

代码语言:javascript
复制
func main() {
    var b = false;
    if b { 
        fmt.Println("b is true")
    } else {
        fmt.Println("b is false")
    }   
}
  • else不能单启一行,否则会报错。比如
代码语言:javascript
复制
if b{
}
else{
}
  • if判断中的b可以使用()括起来。

5.3 使用else if语句

代码语言:javascript
复制
func main() {
    var b int = 2;
    if (b == 1) {
        fmt.Println("b is 1")
    } else if b == 2{
        fmt.Println("b is 2")
    }
}

5.4 使用比较运算符

关于Go语言中的比较运算符,一个要点是两个操作数的类型必须相同。例如,无法对字符串和整数进行比较。

5.5 使用算术运算符

算术运算符也只能用于类型相同的操作数。

代码语言:javascript
复制
var a float32 = 1.1
var c int = 1;

fmt.Println(a + c)

运行时会报错

代码语言:javascript
复制
invalid operation: a + c (mismatched types float32 and int)

5.7 使用switch语句

代码语言:javascript
复制
func main() {
    fmt.Println("Hello, World!")
    i := 9
    switch i{
        case 2:
            fmt.Println("two")
        case 9:
            fmt.Println("nine")
        case 10:
            fmt.Println("ten")
        default:
            fmt.Println("what's wrong")
    }
}

不同于大多数语言,go的switch中没有break!

5.8 使用for语句进行循环

只包含条件的for语句

代码语言:javascript
复制
func main() {
    i := 0;
    for i<10{
        i++;
        fmt.Println("i is", i)
    }
}

5.8.1 包含初始化语句和后续语句的for语句

代码语言:javascript
复制
func main() {
    for i:=0; i<10; i++{
        fmt.Println("i is", i)
    }
}

注意,for之后的初始化及条件不能用()括号起来!

5.8.2 包含range子句的for语句

代码语言:javascript
复制
package main

import (
    "fmt"
)

func main() {
    numbers := []int{1,3,5,7}
    for i,n := range numbers{
        fmt.Printf("index is %d, value is %d\n", i, n)
    }
}

解读:

  • 声明变量numbers,并将一个包含4个整数的数组赋给它。
  • for语句指定了迭代变量i,用于存储索引值。这个变量将在每次迭代结束后更新。
  • for语句指定了迭代变量n,用于存储来自数组中的值。它也将在每次迭代结束后更新。

5.9 使用defer语句

defer能够让您在函数返回前执行另一个函数。函数在遇到return语句或到达函数末尾时返回。defer语句通常用于执行清理操作或确保操作(如网络调用)完成后再执行另一个函数。

代码语言:javascript
复制
func main() {
    defer fmt.Println("first defer")
    defer fmt.Println("second defer")
    defer fmt.Println("third defer")

    fmt.Println("Hello, World!")
}

结果:

代码语言:javascript
复制
Hello, World!
third defer
second defer
first defer

外部函数执行完毕后,按与defer语句出现顺序相反的顺序执行它们指定的函数。

第6章数组、切片和映射

6.1 使用数组

要创建数组,可声明一个数组变量,并指定其长度和数据类型。

代码语言:javascript
复制
var cheeses [2]string
  • 使用关键字var声明一个名为cheeses的变量。
  • 将一个长度为2的数组赋给这个变量。
  • 这个数组的类型为字符串。

6.2 使用切片

切片是底层数组中的一个连续片段,通过它您可以访问该数组中一系列带编号的元素。

为何要使用切片?

在Go语言中,使用数组存在一定的局限性。采用前面的数组cheeses表明方试,您无法在数组中添加元素;然而切片比数组更灵活,您可在切片中添加和删除元素,还可复制切片中的元素。可将切片视为轻量级的数组包装器,它既保留了数组的完整性,又比数组使用起来更容易。

要声明一个长度为2的空切片,可使用如下语法。

代码语言:javascript
复制
var cheeses = make([]string, 2)
  • 使用关键字var声明一个名为cheeses的变量。
  • 在等号右边,使用Go内置函数make创建一个切片,其中第一个参数为数据类型,而第二个参数为长度。在这里,创建的切片包含两个字符串元素。
  • 将切片赋给变量cheeses。

看下面这个例子

代码语言:javascript
复制
func main() {
    var cheeses = make([]string, 2)
    var books [2]string
    fmt.Println(reflect.TypeOf(cheeses), len(cheeses));
    fmt.Println(reflect.TypeOf(books), len(books));
}

输出

代码语言:javascript
复制
[]string 2
[2]string 2
  • books为数组,cheeses为切片
  • 两者长者均为2,但TypeOf的结果是有差别的。

6.2.1 在切片中添加元素

Go语言提供了内置函数append,让您能够增大切片的长度。append会在必要时调整切片的长度,但它对程序员隐藏了这种复杂性。

代码语言:javascript
复制
var books = make([]string, 2)
books = append(books, "book3");

函数append也是一个不定参数函数。这意味着使用函数append可在切片末尾添加很多值。

代码语言:javascript
复制
var books = make([]string, 2)
books = append(books, "b3", "b4", "b5");
fmt.Println(books, len(books));

结果

代码语言:javascript
复制
[  b3 b4 b5] 5

6.2.2 从切片中删除元素

要从切片中删除元素,也可使用内置函数append。在下面的示例中,删除了索引1处的元素。

代码语言:javascript
复制
package main

import (
    "fmt"
)

func main() {
    var books = make([]string, 3)
    books[0] = "b0";
    books[1] = "b1";
    books[2] = "b2";
    fmt.Println(books, len(books));
    
    var index int = 1;
    books = append(books[:index], books[index+1:]...);
    fmt.Println(books, len(books));
}

6.2.3 复制切片中的元素

要复制切片的全部或部分元素,可使用内置函数copy。在复制切片中的元素前,必须再声明一个类型与该切片相同的切片,例如,不能将字符串切片中的元素复制到整数切片中。

代码语言:javascript
复制
func main() {
    var books = make([]string, 3)
    books[0] = "b0";
    books[1] = "b1";
    books[2] = "b2";
    fmt.Println(books, len(books));
    
    var another = make([]string, 2)
    copy(another, books[])
    fmt.Println(another, len(another));
}
  • another长度只有2,所以copy后只含b0, b1两个元素。

函数copy在新切片中创建元素的副本,因此修改一个切片中的元素不会影响另一个切片。

还可将单个元素或特定范围内的元素复制到新切片中。

代码语言:javascript
复制
copy(another, books[1:])

上述代码从books的第1个元素开始复制。执行后,another中的元素为b1,b2

6.3 使用映射

数组和切片是可通过索引值访问的元素集合,而映射是通过键来访问的无序元素编组。映射在信息查找方面的效率非常高,因为可直接通过键来检索数据。简单地说,映射可视为键-值对集合。

只需一行代码就可声明并创建一个空映射。

代码语言:javascript
复制
var players = make(map[string]int) 

解读

  • 关键字var声明一个名为players的变量。
  • 在等号右边,使用Go语言内置函数make创建了一个映射,其键的类型为字符串,而值的类型为整数。
  • 将这个空映射赋给了变量players。

向映射中添加元素

代码语言:javascript
复制
func main() {
    var players = make(map[string]int) 
    players["sheep"] = 5 
    players["chicken"] = 2 
    players["mouse"] = 0
    fmt.Println(players)
}

注意: 做为key的字串必须使用双引号括起来,如果使用单引号会报错。

从映射中删除元素

代码语言:javascript
复制
delete(players, "mouse")

6.5 问与答

问:该使用数组还是切片?

答:除非确定必须使用数组,否则请使用切片。切片能够让您轻松地添加和删除元素,还无须处理内存分配问题。

问:没有从切片中删除元素的内置函数吗?

答:不能将delete用于切片。没有专门用于从切片中删除元素的函数,但可使用内置函数append来完成这种任务。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/06/18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第4章 函数
    • 4.1 函数是什么
      • 4.1.2 返回单个值
      • 4.1.3 返回多个值
    • 4.2 定义不定参数函数
      • 4.3 使用具名返回值
        • 4.4 使用递归函数
          • 4.5 将函数作为值传递
          • 第5章控制流程
            • 5.2 使用else语句
              • 5.3 使用else if语句
                • 5.4 使用比较运算符
                  • 5.5 使用算术运算符
                    • 5.7 使用switch语句
                      • 5.8 使用for语句进行循环
                        • 5.8.1 包含初始化语句和后续语句的for语句
                        • 5.8.2 包含range子句的for语句
                      • 5.9 使用defer语句
                      • 第6章数组、切片和映射
                        • 6.1 使用数组
                          • 6.2 使用切片
                            • 6.2.1 在切片中添加元素
                            • 6.2.2 从切片中删除元素
                            • 6.2.3 复制切片中的元素
                          • 6.3 使用映射
                            • 6.5 问与答
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档