go语言最主要的特性

栏目: Go · 发布时间: 5年前

内容简介:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Nick_666/article/details/79182138

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Nick_666/article/details/79182138

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

自动垃圾回收

更丰富的内置类型

函数多返回值

错误处理

匿名函数和闭包

类型和接口

并发编程

反射

语言交互性

1、自动垃圾回收

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

2、更丰富的内置类型

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

3、函数返回多值

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

func getName()(firstName, middleName, lastName, nickName string){

return "May", "M", "Chen", "Babe"

}

func getName()(firstName, middleName, lastName, nickName string){ 

firstName = "May"

middleName = "M"

lastName = "Chen"

nickName = "Babe"

return

}

_, _, lastName, _ := getName()

4、错误处理

3个重要关键字defer、panic、recover

defer是函数结束后执行,呈先进后出;

panic是程序出现无法修复的错误时使用,但会让defer执行完;

recover会修复错误,不至于程序终止。当不确定函数不会出错时使用defer+recover

package main
import (
	"log"
func fixError() {
	if r := recover(); r != nil {
		log.Printf("err caught: %v", r)
	} else {
		log.Println("no err")
	}
}
func myDivide(x, y int) int {
	return x / y
}
func testFunc() {
	defer fixError()
	myDivide(6, 0)
}
func main() {
	testFunc()
	log.Println("main end")
}

/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、匿名函数和闭包

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

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

闭包是可以包含自由变量的代码块,这些变量不在这个代码块内或者任何全局上下文中定义,而是在定义代码块的环境中定义。

闭包的价值在于可以作为函数对象或者匿名函数,存储到变量中作为参数传递给其他函数,能够被函数动态创建和返回。

package main
import (
	"fmt"
func main() {
	var j int = 5
	a := func() func() {
		var i int = 10
		return func() {
			fmt.Printf("i, j: %d, %d\n", i, j)
		}
	}()
	a()
	j *= 2
	a()
}

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

i, j: 10, 5

i, j: 10, 10

成功: 进程退出代码 0.

再看个复杂的:

package main
import "fmt"
func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}
func main() {
	pos := adder()
	n := 10
	fmt.Println(pos(n))
}

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

func main() {
	pos := adder()
	n := 10
	fmt.Println(pos(n))
	fmt.Println(pos(n))
	fmt.Println(pos(n))
}

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

10

20

30

成功: 进程退出代码 0.

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

sum := 0
	return func(x int) int {
		sum += x
		return sum
	}

但是sum是一个闭包变量,或者理解为仅初始化一次,且是一个静态变量。备注:return之前的代码仅执行一次。

如下面示例代码,sum:=0和sum=9都仅执行一次:

package main
import "fmt"
func adder() func(int) int {
	sum := 0
	sum = 9
	return func(x int) int {
		sum += x
		return sum
	}
}
func main() {
	pos := adder()
	n := 10
	fmt.Println(pos(n))
	fmt.Println(pos(n))
	fmt.Println(pos(n))
}

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

19

29

39

成功: 进程退出代码 0.

6、类型和接口

类型非常接近于 C语言 中的结构体,也使用了struct。go语言类型不支持继承和重载,仅有封装和组合。

go语言引入了强大的“非侵入式”接口,无需指明类型实现了哪个接口。

7、并发编程

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

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

8、反射

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

package main
import (
	"fmt"
	"reflect"
type Bird struct {
	Name           string
	LifeExpectance int
}
func (b *Bird) Fly() {
	fmt.Println("I am flying...")
}
func main() {
	sparrow := &Bird{"Sparrow", 3}
	s := reflect.ValueOf(sparrow).Elem()
	typeOfT := s.Type()
	for i := 0; i < s.NumField(); i++ {
		f := s.Field(i)
		fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f.Type(),
			f.Interface())
	}
}

/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既是语言特性,同时也是一个 工具 的名称。

package main
//#include <stdio.h>
import "C"
func main() {
	cstr := C.CString("ab, Hello, world")
	C.puts(cstr)
	println(*cstr)
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

菜鸟侦探挑战数据分析

菜鸟侦探挑战数据分析

[日] 石田基广 / 支鹏浩 / 人民邮电出版社 / 2017-1 / 42

本书以小说的形式展开,讲述了主人公俵太从大学文科专业毕业后进入征信所,从零开始学习数据分析的故事。书中以主人公就职的征信所所在的商业街为舞台,选取贴近生活的案例,将平均值、t检验、卡方检验、相关、回归分析、文本挖掘以及时间序列分析等数据分析的基础知识融入到了生动有趣的侦探故事中,讲解由浅入深、寓教于乐,没有深奥的理论和晦涩的术语,同时提供了大量实际数据,使用免费自由软件RStudio引领读者进一步......一起来看看 《菜鸟侦探挑战数据分析》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器