赞
踩
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
1.文件名必须是_test.go结尾的,这样在执行go test的时候才会执行到相应的代码
2.你必须import testing这个包
3.所有的测试用例函数必须是Test开头
4.测试用例会按照源代码中写的顺序依次执行
5.测试函数TestXxx()的参数是testing.T,我们可以使用该类型来记录错误或者是测试状态
6.测试格式:func TestXxx (t *testing.T),Xxx部分可以为任意的字母数字的组合,
但是首字母不能是小写字母[a-z],例如Testintdiv是错误的函数名。
7.函数中通过调用testing.T的Error, Errorf, FailNow, Fatal, FatalIf方法,说明测试不通过,调用Log方法用来记录测试的信息。
一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。1808年,基斯顿·卡曼引进这个表示法。
package main
import “fmt”
func factorial(i int) int {
if i <= 1 {
return 1
}
return i * factorial(i-1)
}
func main() {
var i int = 7
fmt.Printf(“Factorial of %d is %d\n”, i, factorial(i))
}
//输出结果:
Factorial of 7 is 5040
这个数列从第3项开始,每一项都等于前两项之和。
package main
import “fmt”
func fibonaci(i int) int {
if i == 0 {
return 0
}
if i == 1 {
return 1
}
return fibonaci(i-1) + fibonaci(i-2)
}
func main() {
var i int
for i = 0; i < 10; i++ {
fmt.Printf(“%d\n”, fibonaci(i))
}
}
//输出结果:
0
1
1
2
3
5
8
13
21
34
=================================================================================
程序开发中经常要创建资源(数据库初始化连接,文件句柄,锁等),在程序执行完毕都必须得释放资源,Go提供了defer(延时机制)更方便、更及时的释放资源。
内置关键字defer 用于延迟调用
defer在return
前执行,常用于资源释放
多个defer按 先进后出
的机制执行
defer语句的变量,在defer声明时定义
显式 return 返回前,会先修改命名返回参数
defer用途:
关闭文件
句柄
锁
资源释放
数据库
连接释放
defer 是先进后出
后面的语句会依赖
前面的资源,因此如果先前面的资源先释放了
,后面的语句就没法执行
了。
package main
import “fmt”
func main() {
var whatever [5]struct{}
for i := range whatever {
defer fmt.Println(i)
}
}
//结果
4
3
2
1
0
package main
import (
“fmt”
)
func testDefer1() {
//defer机制 先入后出,如同羽毛球筒
defer fmt.Println(“hello v1”) //顺序5
defer fmt.Println(“hello v2”) //顺序4
defer fmt.Println(“hello v3”) //顺序3
fmt.Println(“aaaaa”) // 顺序1
fmt.Println(“bbbb”) //顺序2
}
func testDefer2() {
for i := 0; i < 5; i++ {
//每次循环,defer将后入的语句压到defer栈
//依旧先入后出
defer fmt.Printf(“i=%d\n”, i)
}
fmt.Printf(“running\n”) //顺序1
fmt.Printf(“return\n”) //顺序2
}
func testDefer3() {
var i int = 0
//defer是声明时定义好的,之后再修改无效,因此i=0
defer fmt.Printf(“defer i=%d\n”, i)
i = 1000
fmt.Printf(“i=%d\n”, i)
}
func main() {
//testDefer1()
//testDefer2()
testDefer3()
}
如果defer遇到了闭包
package main
import “fmt”
func main() {
var whatever [3]struct{}
for i := range whatever {
defer func() { fmt.Println(i) }()
}
}
//相当于
i结果最后为2,因为闭包原因,所以i最终为2
//结果,
2
2
2
package main
import “fmt”
type Test struct {
name string
}
func (t *Test) Close() {
fmt.Println(t.name, " closed")
}
func main() {
ts := []Test{{“a”}, {“b”}, {“c”}}
for _, t := range ts {
defer t.Close()
}
}
//预计的输出c b a,而是输出c c c
//结果
c closed
c closed
c closed
将defer t.Close()改为defer Close(t)
输出结果:
c closed
b closed
a closed
省去函数,可以用t.Close()
package main
import “fmt”
type Test struct {
name string
}
func (t *Test) Close() {
fmt.Println(t.name, " closed")
}
func main() {
ts := []Test{{“a”}, {“b”}, {“c”}}
for _, t := range ts {
t2 := t
defer t2.Close()
}
}
c closed
c closed
c closed
结论:
defer后面的语句在执行的时候,函数调用的参数会被保存起来
,但是不执行
。也就是复制了一份。但是并没有说struct这里的this指针如何处理,通过这个例子可以看出go语言并没有
把这个明确写出来的this指针当作参数
来看待。
多个 defer 注册,按 FILO
次序执行 ( 先进后出 )。
异常也会输出
package main
func test(x int) {
defer println(“a”)
defer println(“b”)
defer func() {
println(100 / x) // div0 异常未被捕获,逐步往外传递,最后终止进程。
}()
defer println(“c”)
}
func main() {
test(0)
}
//结果
c
b
a
panic: runtime error: integer divide by zero
*
延迟调用参数在注册时求值或复制,可用指针或闭包 “延迟” 读取。
package main
func test() {
x, y := 10, 20
defer func(i int) {
println(“defer:”, i, y) // y 闭包引用
}(x) // x 被复制
x += 10
y += 100
println(“x =”, x, “y =”, y)
}
func main() {
test()
}
输出结果:
x = 20 y = 120
defer: 10 120
*
滥用 defer 可能会导致性能问题,例如:在一个 “大循环
” 里。
package main
import (
“fmt”
“sync”
“time”
)
var lock sync.Mutex
func test() {
lock.Lock()
lock.Unlock()
}
func testdefer() {
lock.Lock()
defer lock.Unlock()
}
func main() {
func() {
t1 := time.Now()
for i := 0; i < 10000; i++ {
test()
}
elapsed := time.Since(t1)
fmt.Println("test elapsed: ", elapsed)
}()
func() {
t1 := time.Now()
for i := 0; i < 10000; i++ {
testdefer()
}
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
unc test() {
lock.Lock()
lock.Unlock()
}
func testdefer() {
lock.Lock()
defer lock.Unlock()
}
func main() {
func() {
t1 := time.Now()
for i := 0; i < 10000; i++ {
test()
}
elapsed := time.Since(t1)
fmt.Println("test elapsed: ", elapsed)
}()
func() {
t1 := time.Now()
for i := 0; i < 10000; i++ {
testdefer()
}
[外链图片转存中…(img-9J3q4oOt-1715566616639)]
[外链图片转存中…(img-94hdXjKD-1715566616640)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。