zoukankan      html  css  js  c++  java
  • go笔记

    学习网站:https://studygolang.gitbook.io/learn-go-with-tests/go-ji-chu/hello-world#bian-xie-ce-shi

    编写测试

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

    • 程序需要在一个名为 xxx_test.go 的文件中编写

    • 测试函数的命名必须以单词 Test 开始

    • 测试函数只接受一个参数 t *testing.T

    现在这些信息足以让我们明白,类型为 *testing.T 的变量 t 是你在测试框架中的 hook(钩子),所以当你想让测试失败时可以执行 t.Fail() 之类的操作。

     

    t.Errorf

    我们调用 tErrorf 方法打印一条消息并使测试失败。error后面的f 表示格式化,它允许我们构建一个字符串,并将值插入占位符值 %q 中。当你的测试失败时,它能够让你清楚是什么错误导致的。

     

     

    介绍了一种叫做TDD的程序设计方法论,即测试驱动开发(Test-Driven development)

    去查了一下这个东西:https://juejin.cn/post/6844903925842198536

    TDD三原则

    1. 除非为了通过一个单元测试,否则不允许编写任何产品代码。
    2. 在一个单元测试中只允许编写刚好能够导致失败的内容。
    3. 一次只能写通过一项单元测试的产品代码,不能多写。
    1. You are not allowed to write any production code unless it is to make a failing unit test pass.
    2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
    3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
    太难用了

    3.6

    for循环

    go里面没有whiledountil 这几个关键字,

    for循环的变体

    package main
    
    import "fmt"
    
    func main() {
    
    	i := 1
    	for i <= 3 {
    		fmt.Println(i)
    		i = i + 1
    	}
    	fmt.Println("")
    
    	for j := 7; j <= 9; j++ {
    		fmt.Println(j)
    	}
    	fmt.Println("")
    
    	for {
    		fmt.Println("loop")
    		break
    	}
    	fmt.Println("")
    
    	for n := 0; n <= 5; n++ {
    		if n%2 == 0 {
    			continue
    		}
    		fmt.Println(n)
    	}
    	fmt.Println("")
    }
    
    // 1
    // 2
    // 3

    // 7
    // 8
    // 9

    // loop

    // 1
    // 3
    // 5
    数组
    数组的容量是我们在声明它时指定的固定值。我们可以通过两种方式初始化数组:
    [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}
    举个栗子:
    number := [5]int{1, 2, 3, 4, 5}

     
    空白标志符
    看两个代码
    array := [5]int{1, 2, 3, 4, 5}
    s := 0
    for i, arr := range array {
    	s += arr
    	fmt.Println("i=", i, "  s=", s, "  arr=", arr)
    }
    // i= 0   arr 1   s=%d 1
    // i= 1   arr 2   s=%d 3
    // i= 2   arr 3   s=%d 6
    // i= 3   arr 4   s=%d 10
    // i= 4   arr 5   s=%d 15
    
    array := [5]int{1, 2, 3, 4, 5}
    s := 0
    for _, arr := range array {
    	s += arr
    	fmt.Println("  s=", s, "  arr=", arr)
    }
    // s= 1   arr= 1
    // s= 3   arr= 2
    // s= 6   arr= 3
    // s= 10   arr= 4
    // s= 15   arr= 5
    

     空白标识符可以接收一个不需要用的参数,最常用的地方就是在 使用range 迭代数组时,每次迭代都会返回数组元素的索引和值。我们选择使用 _ 空白标志符 来忽略索引。

    3.7

    函数

    函数可变参数

    func SumAll(numberToSum ...[]int) (sums []int) {
    	return
    }
    

     方法 reflect.DeepEqual

    这个方法在比较两个数组元素是否完全相同时很好用

    func TestSumAll(t *testing.T) {
    	got := SumAll([]int{1, 2}, []int{0, 9})
    	want := []int{3, 9}
    	if !reflect.DeepEqual(got, want) {
    		t.Errorf("got %v want %v", got, want)
    	}
    }
    

     两个数组完全相同返回true,否则返回false

    方法make

    一种创建切片的新方式。make 可以在创建切片的时候指定我们需要的长度和容量。
    我们可以使用切片的索引访问切片内的元素,使用 = 对切片元素进行赋值。

    sums = make([]int, lengthOfNumbers)
    

    切片处理

    使用语法 slice[low:high] 获取部分切片,比如

    numbers[1:4]
    

     就可以获取到从第二个到第五个元素,如果在冒号的一侧没有数字就会一直取到最边缘的元素,比如

    numbers[1:]
    

     就可以获取到从第二个开始到最后的元素

    结构体

    go定义结构体和c语言一样,在定义方法时有所区别,不过在调用的时候是一样的

    type Rectangle struct {
    	//矩阵
    	Width  float64
    	Height float64
    }
    
    func (r Rectangle) Area() float64 {
    	return (r.Height * r.Width)
    }
    
    type Circle struct {
    	//圆
    	Radius float64
    }
    
    func (r Circle) Area() float64 {
    	return (math.Pi * r.Radius * r.Radius)
    }
    
    rectangle := Rectangle{12.0, 6.0}
    got := rectangle.Area()    
    circle := Circle{10.0}
    got := circle.Area()
    

     接口

     https://www.zhihu.com/question/318138275

    稍微学习了一下接口的意思,但还是比较模糊。知乎里说到的鸭子模型,只要它能达到我所设置的成为鸭子的条件,那它就是鸭子。

    package main
    
    import (
    	"fmt"
    )
    
    //手机接口
    type Phone interface {
    	call()
    }
    
    type NokiaPhone struct {
    }
    
    func (nokiaPhone NokiaPhone) call() {
    	fmt.Println("I am Nokia, I can call you!")
    }
    
    type IPhone struct {
    }
    
    func (iPhone IPhone) call() {
    	fmt.Println("I am iPhone, I can call you!")
    }
    
    //电脑接口
    type Computer interface {
    	play()
    }
    
    type PersonalComputer struct {
    }
    
    func (personalcomputer PersonalComputer) play() {
    	fmt.Println("I am personalcomputer")
    }
    
    type LapTop struct {
    }
    
    func (laptop LapTop) play() {
    	fmt.Println("I am laptop")
    }
    
    //乱入了一台假装自己是手机的笔记本
    func (laptop LapTop) call() {
    	fmt.Println("I can be a phone ")
    }
    
    func main() {
    	var phone Phone
    
    	phone = new(NokiaPhone)
    	phone.call()
    
    	phone = new(IPhone)
    	phone.call()
    
    	phone = new(LapTop)
    	phone.call()
    
    	var computer Computer
    	computer = new(PersonalComputer)
    	computer.play()
    	computer = new(LapTop)
    	computer.play()
    	// computer.call()
    
    	
    	
    	
    	
    }
    

     可以看到在两种手机,两种电脑中,乱入了一台假装自己是手机的电脑,当LapTop定义了这样两个方法后,它即实现了手机这个接口,又实现了电脑这个接口。于是出现了下面的情况

    phone = new(LapTop)
    phone.call()
    computer = new(LapTop)
    computer.play()
    

     但是只得注意的是,computer.call()并不能执行,虽然这里的computer本质是LapTop,而LapTop有call()这个方法,但是因为接口的关系,它在这里只能成为computer(好像有点绕)

    用蓝皮书上说的,接口就是一种约定

  • 相关阅读:
    TCP校验和
    Python8 数据库基础
    Python7 TCPIP协议与抓包
    Python6 线程与进程、网络编程、生成器与迭代器、协程、异步IO
    python2 变量与数据类型
    Python10 前端基础与爬虫
    Python11 Scrapy框架基础
    python3 函数、运算符与数据类型的常用方法
    Python9 数据库进阶
    python1 简介
  • 原文地址:https://www.cnblogs.com/This-is-Y/p/14492860.html
Copyright © 2011-2022 走看看