雀恰营销
专注中国网络营销推广

接口类型,Go语言学习函数+结构体+方法+接口

接口类型,Go语言学习函数+结构体+方法+接口

func(data int) {
   fmt.Println("hello", data)
}(100)

将匿名函数分配给变量

可以为匿名函数体赋值,例如:

// 将匿名函数体保存到f()中
f := func(data int) {
     fmt.Println("hello", data)
}
// 使用f()调用
f(100)

匿名函数用作回调函数

使用时定义一个匿名函数,而不是先在被调用函数中声明,这才是callback的本质

// 遍历切片的每个元素,通过给定函数进行元素访问
 func visit(list []int, f func(int)) {
      for _, v := range list {
            f(v)
      }
 }
 func main() {
     // 使用匿名函数打印切片内容
      visit([]int{1, 2, 3, 4}, func(v int) {
            fmt.Println(v)
      })
 }

可变参数 – 具有不确定数量参数的函数形式

所有参数都是可变参数:fmt.Println

func Println(a ...interface{}) (n int, err error) {
  return Fprintln(os.Stdout, a...)
}

使用 fmt.Println 时,传入的值类型不受限制,例如:

fmt.Println(5, "hello", &struct{ a int }{1}, true)

当可变参数为 interface{} 类型时,可以传入任何类型的值

一些参数是可变的: fmt.Printf

fmt.Printf的第一个参数是参数列表,后面的参数是可变参数:

func Printf(format string, a ...interface{}) (n int, err error) {
	return Fprintf(os.Stdout, format, a...)
}
------------------------------------------------------
fmt.Printf("pure stringn")
fmt.Printf("value: %v %fn", true, math.Pi)

1.3 个闭包

闭包可以理解为在函数内部定义的函数。本质上,闭包是函数内部和函数外部之间的桥梁。简单来说,闭包=函数+引用环境

func main() {
	var f = add()
	fmt.Printf("f(10): %vn", f(10))
	fmt.Printf("f(20): %vn", f(20))
	// f(10): 10
	// f(20): 30
}
func add() func(int) int {
	var x int
	return func(y int) int {
		x += y
		return x
	}
}

1.4 延迟语句

defer语句延迟后面的语句,defer语句以先进后出的方式执行(第一个defer语句最后执行,后面的defer语句先执行)。

特征:

采用:

处理运行时错误

Go语言的错误处理思路和设计包括以下特点:

错误接口定义格式

error 是 Go 系统声明的接口类型。代码如下:

type error interface {
  Error() string    // 返回错误的具体描述.
}

所有符合 Error() 字符串格式的接口都实现了 Error 接口。

定义错误

在 Go 语言中,使用 errors 包定义错误,格式如下:

var err = errors.New("this is an error")

因为错误字符串是比较固定的,所以一般在包作用域中声明,应该尽量减少直接使用errors.new在使用的时候返回。

恐慌 – 程序停止运行

手动触发停机

Go语言可以在程序中手动触发宕机,使程序崩溃,让开发者及时发现错误,减少可能的损失。

当 Go 语言程序宕机时,会将栈和 goroutine 信息输出到控制台,所以宕机时也可以很容易的知道错误的位置。

package main
func main() {
panic("crash")
}

panic() 的参数可以是任何类型,

当 panic() 触发的崩溃发生时,panic() 之后的代码不会被执行,但是在 panic() 函数之前已经运行的 defer 语句在崩溃发生时仍然会生效。

接口类型,Go语言学习函数+结构体+方法+接口

1.5 崩溃恢复(recover)——防止程序崩溃

无论是Runtime层针对代码运行错误抛出的panic crash,还是主动触发的panic crash,都可以配合defer和recover实现错误捕获和恢复,让代码在crash后继续运行发生。

Go没有异常系统,其使用panic触发宕机与其他语言抛出异常类似,所以recover的宕机恢复机制对应try/catch机制。

恐慌与恢复的关系:

提示:虽然panic/recover可以模拟其他语言的异常机制接口类型,但不建议在编写普通函数时频繁使用该功能。

2. 结构

结构成员由一系列成员变量组成,也称为“字段”。

字段具有以下属性:

Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念。

Go 语言中的结构体和“类”是复合结构体,但是 Go 语言中结构体的内联匹配接口比面向对象更具有可扩展性和灵活性。

Go 语言不仅认为结构可以有方法,而且每个自定义类型也可以有自己的方法。

2.1 给结构体定义和赋值

基本形式:

type Point struct {
	X int
	Y int
}
var p Point
p.X = 10
p.Y = 20

结构体的定义只是对内存布局的描述接口类型,Go语言学习函数+结构体+方法+接口,只有当结构体实例化时,才会真正分配内存

创建一个指针类型的结构:

获取结构的地址并实例化它:

//使用结构体定义一个命令行指令(Command),指令中包含名称、变量关联和注释等
type Command struct {
	name string
	Var *int
	comment string
}
var version int = 1
cmd := &Command{}
cmd.name = "version"
cmd.Var = &version
cmd.comment = "show version"

使用键值对填充结构:

type People struct {
	name string
	child *People
}
relation := &People{
	name: "爷爷"
	child: &People{
		name: "爸爸"
		child: &People{
			name: "我"
		},
	}
}

3. 方法

Go 中的方法是作用于特定类型变量的函数。这种特殊类型的变量称为接收器。

当特定类型被理解为结构或“类”时,接收者的概念与其他语言中的 this 或 self 类似。

3.1 结构体方法

创建一个背包 Bag 结构体接口类型,Go语言学习函数+结构体+方法+接口,该结构体定义方法 insert 以将物品放入背包:

type Bag struct {
	items[] int
}
func (b *Bag) insert(itemid int) {
	b.items = append(b.items, itemid)
} 
func main() {
	b := new(Bag)
	b.insert(1001)
}

接口类型,Go语言学习函数+结构体+方法+接口

(b*Bag) 表示接收者,即 Insert 作用的对象实例。每种方法只能有一个接收器。

3.2 接收器

接收者是方法动作的目标

接收器可以按照接收器的类型来划分:

指针接收器

由于指针的特性,调用方法时,接收者指针的任何成员变量都会被修改,修改在方法结束后生效。

// 定义属性结构
type Property struct {
	value int
}
// 设置属性值方法
func (p *Property) setVal(val int) {
	p.value = val
}
// 获取属性值方法
func (p *Property) getVal() int {
	return p.value
}
func main() {
	p := new(Property)
	p.value = 123
	fmt.Println(p.getVal())
	p.setVal(666)
	fmt.Println(p.getVal())
}

非指针型接收器

当方法作用于非指针接收器时,Go 在代码运行时复制接收器的值。接收者的成员值可以在非指针接收者的方法中获取,但修改后无效。

type Point struct {
	x, y int
}
func (p Point) add(other Point) Point {
	return Point{p.x + other.x, p.y + other.y}
}
func main() {
	// 初始化点
	p1 := Point{1, 1}
	p2 := Point{2, 2}
	res := p1.add(p2)
	fmt.Println(res)
	p3 := Point{3, 3}
	p4 := p1.add(p2).add(p3)
	fmt.Println(p4)
}

指针接收器和非指针接收器的使用:

指针和非指针接收器的使用 在计算机中,小对象适合使用非指针接收器,因为它们的值复制速度更快。由于复制性能低,大对象适用于指针接收器。在接收者和参数之间传递时,不执行复制,而是传递指针。

4. 接口

接口是双方约定的合作协议。接口实现者不需要关心接口将如何使用接口类型,调用者也不需要关心接口的实现细节。接口是一种类型和一种抽象结构,它不公开其包含的数据的格式、类型和结构。

赞(0) 打赏
未经允许不得转载:雀恰营销 » 接口类型,Go语言学习函数+结构体+方法+接口
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

文章对你有帮助就赞助我一下吧

支付宝扫一扫打赏

微信扫一扫打赏