Go语言培训

本课程培训目标

通过本课程能编写Go的Web小程序,让大家对Go有点小兴趣

哪些公司、平台在使用Go语言

B站、七牛云、K8s

Go语言优势

占用内存小,并发编程上手简单
适合容器化部署
适合C语言程序员上手

Go语言劣势

第三方类库没有java丰富

Go语言特征

1.自动立即回收
2.更丰富的内置类型
3.函数多返回值
4.错误处理
5.匿名函数和闭包
6.类型和接口
7.并发编程
8.反射
9.语言交互性

Go没有的语言特征

没有继承,不面向对象

Go语言基础语法

  1. 关键字import、if else、for(没有while)、switch、指针
  2. 特性:
  3. 高级特性: 协程、管道Channel

Hello world

1.安装Go,下载地址

##查看go版本
go version

2.安装IDE。可以使用VSCode(前端经验入门), Idea的GoLand(java经验入门)
3.创建文件夹go-playground,使用Idea打开这个文件夹
4.在根目录下,创建main.go

package main
import "fmt"

func hello() {
  return "Hello, world"
}

func main() {
    fmt.Println("hello world!")
}
  1. 使用go官方的包(package)依赖管理工具go mod,go mod等同于maven、npm、cocoapads等。包依赖管理这个我们下节课在仔细讲。
    在根目录(go-playground)执行: go mod init github.com/wongben/go-playground
    执行后在根目录生成文件go.mod。内容如下:
module github.com/wongben/go-playground
go 1.12

6.在命令行里执行

go build //生成go-playground.exe文件
go run main.go //编译和执行main.go

7.编写测试案例

package main

import "testing"

func TestHello(t *testing.T) {
    got := Hello()
    want := "Hello, world"

    if got != want {
        t.Errorf("got '%q' want '%q'", got, want)
    }
}

编写测试和函数很类似,其中有一些规则:

  • 程序需要在一个名为 xxx_test.go 的文件中编写
  • 测试函数的命名必须以单词 Test 开始
  • 测试函数只接受一个参数 t *testing.T
    现在这些信息让我们明白: 类型为 *testing.T 的变量 t 是你在测试框架中的 hook(钩子),所以当你想让测试失败时可以执行 t.Fail() 之类的操作。

接下来我们把测试类重构一下

package hello

import "testing"

func TestHello(t *testing.T) {
    assertCorrectMessage := func(t *testing.T, got, want string) {
        t.Helper()
        if got != want {
            t.Errorf("got '%q' want '%q'", got, want)
        }
    }

    t.Run("saying hello to people", func(t *testing.T) {
        got := Hello("ben", "en")
        want := "hello, ben"
        assertCorrectMessage(t, got, want)
    })

    t.Run("中文测试", func(t *testing.T) {
        got := Hello("ben","cn")
        want := "你好, ben"
        assertCorrectMessage(t, got, want)
    })

}

这里我们将使用测试库中的另一个工具 -- 子测试。有时,对一个「事情」进行分组测试,然后再对不同场景进行子测试非常有效。
这种方法的好处是,你可以建立在其他测试中也能够使用的共享代码。
当我们检查信息是否符合预期时,会有重复的代码。重构不仅仅是针对程序的代码

int整型

首先,先写测试
这里,我们可以通过编写 示例 更深入地了解测试,标准库的文档中能够找到许多这样的例子。与典型的测试一样,示例是存在于一个包的 _test.go 文件中的函数。向 adder_test.go 文件添加以下 ExampleAdd 函数。

package integers

import (
    "fmt"
    "testing"
)


func ExampleAdd() {
    sum := Add(1, 5)
    fmt.Println(sum)
    // Output: 6
}

func TestAdd(t *testing.T) {
    sum := Add(2, 2)
    expected := 4

    if sum != expected {
        t.Errorf("expected '%d', but got '%d'", expected, sum)
    }
}
package integers

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

迭代与基准测试

在 Go 中 for 用来循环和迭代,Go 语言没有 while,do,until 这几个关键字,你只能使用 for。

func main() {
    sum := 1
    //初始化语句和后置语句是可选的,等效于for ; sum < 1000; {
        for  sum < 1000  {
        sum += sum
    }
    fmt.Println(sum)
}

迭代

const repeatCount = 5

func Repeat(character string) string {
    var repeated string
    for i := 0; i < repeatCount; i++ {
        repeated += character
    }
    return repeated
}

基准测试

在 Go 中编写基准测试(benchmarks)是该语言的另一个一级特性,它与编写测试非常相似。

func BenchmarkRepeat(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Repeat("a")
    }
}

你会看到上面的代码和写测试差不多。
testing.B 可使你访问隐性命名(cryptically named)b.N。基准测试运行时,代码会运行 b.N 次,并测量需要多长时间。代码运行的次数不会对你产生影响,测试框架会选择一个它所认为的最佳值,以便让你获得更合理的结果。
用 go test -bench=. 来运行基准测试。

数组与分片

  • 先写测试函数
package arrays

import "testing"

func TestSum(t *testing.T) {
    //var n [5]int
    //numbers := [5]int{}
    //numbers := [5]int{1,2,3,4,5}
    //numbers := []int{1,2,3,4,5}
    numbers := [...]int{1,2,3,4,5}
    got := sum(numbers)

    want := 15
    if want != got {
        t.Errorf("got %d want %d given, %v", got, want, numbers)
    }
}

数组的容量是我们在声明它时指定的固定值。我们可以通过两种方式初始化数组:
[N]type{value1, value2, ..., valueN} e.g. numbers := [5]int{1, 2, 3, 4, 5}
[...]type{value1, value2, ..., valueN} e.g. numbers := [...]int{1, 2, 3, 4, 5}

在错误信息中打印函数的输入有时很有用。我们使用 %v(默认输出格式)占位符来打印输入,它非常适用于展示数组。

  • 先使用最少的代码来让失败的测试先跑起来
package arrays

func Sum(numbers [5]int) (sum int) {
    return 0
}

//func Sum(numbers [5]int) (sum int) {
//  for i := 0; i < 5; i++ {
//      sum += numbers[i]
//  }
//  return sum
//}

//func Sum(numbers [5]int) (sum int) {
//  for _, number := range numbers {
//      sum += number
//  }
//  return sum
//}
  • 数组和它的类型

数组有一个有趣的属性,它的大小也属于类型的一部分,如果你尝试将 [4]int 作为 [5]int 类型的参数传入函数,是不能通过编译的。它们是不同的类型,就像尝试将 string 当做 int 类型的参数传入函数一样。

因为这个原因,所以数组比较笨重,大多数情况下我们都不会使用它。

Go 的切片(slice)类型不会将集合的长度保存在类型中,因此它的尺寸可以是不固定的。
下面我们会完成一个动态长度的 Sum 函数。

func Sum(numbers []int) (sum int) {
    for _, number := range numbers {
        sum += number
    }
    return sum
}

我们可以使用 range语法来让函数变得更加整洁。range 会迭代数组,每次迭代都会返回数组元素的索引和值。我们选择使用 _ 空白标志符 来忽略索引。

  • 重构
    我们已经重构了 Sum 函数把参数从数组改为切片。注意不要在重构以后忘记维护你的测试代码。
func TestSum(t *testing.T) {

    t.Run("collection of 5 numbers", func(t *testing.T) {
        numbers := []int{1, 2, 3, 4, 5}

        got := Sum(numbers)
        want := 15

        if got != want {
            t.Errorf("got %d want %d given, %v", got, want, numbers)
        }
    })

    t.Run("collection of any size", func(t *testing.T) {
        numbers := []int{1, 2, 3}

        got := Sum(numbers)
        want := 6

        if got != want {
            t.Errorf("got %d want %d given, %v", got, want, numbers)
        }
    })

}

Go 有内置的计算测试 覆盖率的工具,它能帮助你发现没有被测试过的区域。我们不需要追求 100% 的测试覆盖率,它只是一个供你获取测试覆盖率的方式。只要你严格遵循 TDD 规范,那你的测试覆盖率就会很接近 100%。

运行:
go test -cover

  • 另一个例子
    这回我们需要一个 SumAll 函数,它接受多个切片,并返回由每个切片元素的总和组成的新切片。
    例如:SumAll([]int{1,2}, []int{0,9}) 返回 []int{3, 9}
    或者: SumAll([]int{1,1,1}) 返回 []int{3}

先编写测试


func TestSumAll(t *testing.T) {

    got := SumAll([]int{1,2}, []int{0,9})
    want := []int{3, 9}

    if got != want {
        t.Errorf("got %v want %v", got, want)
    }

https://www.jianshu.com/p/0cbc97bd33fb

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 1.安装 https://studygolang.com/dl 2.使用vscode编辑器安装go插件 3.go语...
    go含羞草阅读 1,538评论 0 6
  • 环境搭建 Golang在Mac OS上的环境配置 使用Visual Studio Code辅助Go源码编写 VS ...
    陨石坠灭阅读 5,772评论 0 5
  • go语言培训班多少钱?这个看你在哪里学了,比如说跟着我的文档节奏走,就不花一分钱,还有相应视频教程(基础视频+高级...
    qfguankefeng阅读 814评论 0 0
  • 不知你也曾像我一样,无论白天还是黑夜,只要想到那个人,心中的柔软一下就被触动了,想她,想她,不断默念着她,终于在某...
    秸杆阅读 296评论 4 2
  • 学习安全型恋人的“吵架公约”关心恋人的需要感情幸福的基本前提是知道恋人的需要和自己的需要同等重要。忽视恋人的需要也...
    Jaychan0907339阅读 370评论 0 0