go语言最主要的特性

https://www.jianshu.com/p/ebacb1ab52ac

go语言最主要特性主要是:

  • 自动垃圾回收
  • 更丰富的内置类型
  • 函数多返回值
  • 错误处理
  • 匿名函数和闭包
  • 类型和接口
  • 并发编程
  • 反射
  • 语言交互性

1、自动垃圾回收

能够像java、C#等语言自带GC,不用再为内存管理苦恼

2、更丰富的内置类型

关键在于内置,像map、slice这些常用的数据类型,内置于builtin,默认包含,无需自己添加。

3、函数返回多值

多值返回仅动态语言Python有此特性

  1. func getName()(firstName, middleName, lastName, nickName string){
  2. return "May", "M", "Chen", "Babe"
  3. }
  4. func getName()(firstName, middleName, lastName, nickName string){
  5. firstName = "May"
  6. middleName = "M"
  7. lastName = "Chen"
  8. nickName = "Babe"
  9. return
  10. }
  11. _, _, lastName, _ := getName()

4、错误处理

3个重要关键字defer、panic、recover
defer是函数结束后执行,呈先进后出;
panic是程序出现无法修复的错误时使用,但会让defer执行完;
recover会修复错误,不至于程序终止。当不确定函数不会出错时使用defer+recover

  1. package main
  2. import (
  3. "log"
  4. )
  5. func fixError() {
  6. if r := recover(); r != nil {
  7. log.Printf("err caught: %v", r)
  8. } else {
  9. log.Println("no err")
  10. }
  11. }
  12. func myDivide(x, y int) int {
  13. return x / y
  14. }
  15. func testFunc() {
  16. defer fixError()
  17. myDivide(6, 0)
  18. }
  19. func main() {
  20. testFunc()
  21. log.Println("main end")
  22. }

/Users/zhaojunyan/go/src/src [/Users/zhaojunyan/go/src]
2018/01/29 12:52:44 err caught: runtime error: integer divide by zero
2018/01/29 12:52:44 main end
成功: 进程退出代码 0.

5、匿名函数和闭包

匿名函数就是一个没有名字的函数,本身也是一个闭包

  1. func main() {
  2. f := func(x, y int) int {
  3. return x + y
  4. }
  5. fmt.Println(f(4, 5))
  6. z := func(x, y int) int {
  7. fmt.Println("匿名函数,直接执行", "x:", x, "y:", y)
  8. return x + y
  9. }(6, 7)
  10. fmt.Println(z)
  11. }

闭包是可以包含自由变量的代码块,这些变量不在这个代码块内或者任何全局上下文中定义,而是在定义代码块的环境中定义。
闭包的价值在于可以作为函数对象或者匿名函数,存储到变量中作为参数传递给其他函数,能够被函数动态创建和返回。

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. var j int = 5
  7. a := func() func() {
  8. var i int = 10
  9. return func() {
  10. fmt.Printf("i, j: %d, %d\n", i, j)
  11. }
  12. }()
  13. a()
  14. j *= 2
  15. a()
  16. }

/Users/zhaojunyan/go/src/src [/Users/zhaojunyan/go/src]
i, j: 10, 5
i, j: 10, 10

成功: 进程退出代码 0.
再看个复杂的:

  1. package main
  2. import "fmt"
  3. func adder() func(int) int {
  4. sum := 0
  5. return func(x int) int {
  6. sum += x
  7. return sum
  8. }
  9. }
  10. func main() {
  11. pos := adder()
  12. n := 10
  13. fmt.Println(pos(n))
  14. }

此时,n是多少,打印出来的就是多少,但是当pos(n)多执行几次,就会发现不同。

  1. func main() {
  2. pos := adder()
  3. n := 10
  4. fmt.Println(pos(n))
  5. fmt.Println(pos(n))
  6. fmt.Println(pos(n))
  7. }

/Users/zhaojunyan/go/src/src [/Users/zhaojunyan/go/src]

10

20

30

成功: 进程退出代码 0.

发现结果,成n的倍数增长。其实pos的函数体虽然是

  1. sum := 0
  2. return func(x int) int {
  3. sum += x
  4. return sum
  5. }

但是sum是一个闭包变量,或者理解为仅初始化一次,且是一个静态变量。备注:return之前的代码仅执行一次。
如下面示例代码,sum:=0和sum=9都仅执行一次:

  1. package main
  2. import "fmt"
  3. func adder() func(int) int {
  4. sum := 0
  5. sum = 9
  6. return func(x int) int {
  7. sum += x
  8. return sum
  9. }
  10. }
  11. func main() {
  12. pos := adder()
  13. n := 10
  14. fmt.Println(pos(n))
  15. fmt.Println(pos(n))
  16. fmt.Println(pos(n))
  17. }

/Users/zhaojunyan/go/src/src [/Users/zhaojunyan/go/src]
19
29
39
成功: 进程退出代码 0.

6、类型和接口

类型非常接近于C语言中的结构体,也使用了struct。go语言类型不支持继承和重载,仅有封装和组合。
go语言引入了强大的“非侵入式”接口,无需指明类型实现了哪个接口。

7、并发编程

go语言倡导使用消息传递来共享内存,引入了goroutine概念,这是一个协程,更轻量级的线程。与channel搭配使用。

  1. package main
  2. import "fmt"
  3. func sum(values []int, resultChan chan int) {
  4. sum := 0
  5. for _, value := range values {
  6. sum += value
  7. }
  8. resultChan <- sum // 将计算结果发送到channel中
  9. }
  10. func main() {
  11. values := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
  12. resultChan := make(chan int, 2)
  13. go sum(values[:len(values)/2], resultChan)
  14. go sum(values[len(values)/2:], resultChan)
  15. sum1, sum2 := <-resultChan, <-resultChan // 接收结果
  16. fmt.Println("Result:", sum1, sum2, sum1+sum2)
  17. }

8、反射

通过反射,你可以获取对象类型的详细信息,并可动态操作对象。反射是把双刃剑,功能强大但代码可读性并不理想。若非必要,不推荐使用反射。

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. type Bird struct {
  7. Name string
  8. LifeExpectance int
  9. }
  10. func (b *Bird) Fly() {
  11. fmt.Println("I am flying...")
  12. }
  13. func main() {
  14. sparrow := &Bird{"Sparrow", 3}
  15. s := reflect.ValueOf(sparrow).Elem()
  16. typeOfT := s.Type()
  17. for i := 0; i < s.NumField(); i++ {
  18. f := s.Field(i)
  19. fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f.Type(),
  20. f.Interface())
  21. }
  22. }

/Users/zhaojunyan/go/src/src [/Users/zhaojunyan/go/src]
0: Name string = Sparrow
1: LifeExpectance int = 3
成功: 进程退出代码 0.
9、语言交互性
由于Go语言与C语言之间的天生联系,Go语言的设计者们自然不会忽略如何重用现有C模块 的这个问题,这个功能直接被命名为Cgo。Cgo既是语言特性,同时也是一个工具的名称。

  1. package main
  2. //#include <stdio.h>
  3. import "C"
  4. func main() {
  5. cstr := C.CString("ab, Hello, world")
  6. C.puts(cstr)
  7. println(*cstr)
  8. }

每天坚持学习1小时Go语言,大家加油,我是彬哥,下期见!如果文章中不同观点、意见请文章下留言或者关注下方订阅号反馈!


社区交流群:221273219
Golang语言社区论坛 :
www.Golang.Ltd
LollipopGo游戏服务器地址:
https://github.com/Golangltd/LollipopGo
社区视频课程课件GIT地址:
https://github.com/Golangltd/codeclass


ft_authoradmin  ft_create_time2019-06-17 17:21
 ft_update_time2019-06-17 17:23