go init函数_Golang教程之函数篇(四)

本文深入探讨了Go语言中的函数、方法和接口。函数在Go中是一等公民,支持多返回值,且有首字母大小写的可见性规则。方法是绑定到特定结构体的函数,接收者决定了方法所属的结构体。接口则体现了Go的鸭子类型,无需显式实现,结构体只要实现了接口所需的方法即可视为实现了该接口。文中还介绍了init()函数的用途和包加载顺序,以及如何利用接口进行类型检查和多态性编程。
摘要由CSDN通过智能技术生成

本篇主要介绍Golang里面的函数、方法以及接口。 首先,说一下函数(function)和方法(method)的区别?其实长的都一样,只不过方法是属于某个对象(或结构体),只有对象自己能调用,而函数则像是公共的,谁都可以调用。

1.函数(function)

在Go里面,函数是一等公民,main函数就是Go程序的执行入口,但是main函数无法被调用。Go里面函数不仅仅可以被调用,而且还可以当作一种类型,所以很容易就可以实现函数式编程。

package mainimport ("fmt""github.com/pkg/errors")func main() {fmt.Printf("Hello World!n")say("12345") //无返回值函数result := Add(1, 2) //有返回值函数fmt.Printf("%dn", result)i, err := divide(12, 2) //多返回值if err != nil {panic(err)}fmt.Printf("%dn", i)}func say(something string) {fmt.Printf("%sn", something)}func Add(a, b int) int {return a + b}func divide(a, b int) (int, error) {if b == 0 {return 0, errors.New("can not divide by zero")}return a / b, nil}//运行结果:/**Hello World!1234536*/

在Go里面定义函数采用func关键字,语法基本上和大部分语言一致,需要特别说明的是Go的函数支持多返回值,这一点特别方便。

在Go里面还有一个隐性约束,如果函数名、结构体成员名、变量名首字母大写则意味着是公开的,可以被其它包引用,否则只能在当前包内使用。

Go里面也有匿名函数(又被称为闭包函数),下面是Go函数一个闭包用法:

package mainimport ("fmt")type addType func(a int) intfunc main() {i := add()fmt.Printf("%Tn", i)fmt.Printf("%v", i(1))}func add() addType {return func(a int) int {return a + 1}}//运行结果:/**main.addType2*/

说到函数就不得不提Go里面一个非常特殊的函数 init(), 这个函数相当于OOP编程里面的构造函数,但是它并不是针对某个类或结构体的,它是一个包级别的初始化函数。

所谓包级别是指当你使用到一个包里面的文件的时候这个函数就会自动执行,这个包里面可能有多个go文件,每个go文件都有可能定义了init函数,如果定义了,那么go就会依次执行init函数,其执行顺序取决于import的顺序。

说到这,借用一张非常经典的Go包加载顺序图:

c9f1e19b07dd8cb0dece5b855b82c8e2.png

在项目里面我们经常会使用init函数去做一些起步工作,比如初始化数据库连接池、加载配置文件。

2.方法(method)

方法和函数基本上一样,只不过它是针对某个结构体而言,说白了,方法是属于某个结构体的。

package mainimport "fmt"func main() {g := goods{name: "苹果"} //初始化结构体g.say()gName := g.getGoodsName() //调用结构体方法fmt.Printf("%sn", gName)}type goods struct {name string}func (goods) say() {fmt.Printf("nothingn")}func (g goods) getGoodsName() string {return g.name}

关于结构体的知识这里简单说下,结构体(struct) 我们可以理解为OOP编程里面的类(class),Go并不是一个完全OOP的语言,但是这并不妨碍我们使用OOP的编程思想。

大家可以看到方法有2个小括号,我们把方法前面那个小括号里面的参数称之为接受者,接受者决定了这个方法属于哪个结构体。

3.接口(interface)

说到OOP不得不说到接口,Go里面的接口和传统OOP编程里面的接口稍微有一些差异,更加灵活,不需要使用 implements 关键字,而是一种隐式的实现。

package mainimport "fmt"func main() {cache := MemCache{data: map[string]string{}}test(cache)}//定义一个Cache接口,只要实现了这2个方法的struct都算实现了该接口type Cache interface {Get(key string) stringSet(key string, value string)}//一个内存缓存type MemCache struct {data map[string]string}func (m MemCache) Get(key string) string {return m.data[key]}func (m MemCache) Set(key string, value string) {m.data[key] = valuefmt.Printf("set %s to %sn", key, value)}//测试,它的参数声明需要的是一个实现了Cache接口的对象func test(cache Cache) {cache.Set("v1", "缓存内容")result := cache.Get("v1")fmt.Printf("get v1: %sn", result)}

Go这种形式被称为duck type,所谓鸭子类型说的是:只要走起路来像鸭子、叫起来也像鸭子,那么就可以把它当作鸭子。

作者:合一研发部-王本俊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值