前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言入门——函数

Go语言入门——函数

作者头像
JackieZheng
发布2019-07-02 17:27:26
4600
发布2019-07-02 17:27:26
举报
文章被收录于专栏:JackieZhengJackieZheng

写了快一个月的Go,已经没有什么陌生感了。

一行代码写完,不会在行尾本能的敲上“;”,直接Enter键换行;

定义变量把变量名放在前面,类型放在后面;

使用struct去定义自己想要的数据模型就好比定义一个Java中的model一样……

这些不用可以经过大脑加工思考,就想自己还在写Java一样。

还记得当时在看《Go实战》的时候看到变量类型后置的声明方式,我还在极力吐槽这种不人性的语法,如果我已经站在了真香的队伍里,和其他的真香同学别无二致。

感慨,人的适应能力真的强?

作为一个Java重度爱好者,其实在每次写Go的时候都会情不自禁的把两者进行对比,在写文章的时候也会经常提到。当然了,今天主要说的还是Go的函数。

1、Go语言中的函数长啥样

代码语言:javascript
复制
func f(a int, b int) (ret int, err error) {
    fmt.Println("This is function")
    return
}

没错,这大概就是一个典型的Go风格的函数,那么它有哪些特色

  • 入参
  • 返回值

2、入参

2.1 参数合并声明

入参的变量也是变量后置的,这里a变量和b变量是相同类型的,所以也可以写成

代码语言:javascript
复制
a, b int

对于不同类型的参数需要分开定义。

2.2 不定参数

除此以外,入参还支持不定参数

比如可以这样定义

代码语言:javascript
复制
func f(args ...int) {
    for _, arg := range args {
        fmt.Println(arg)
    }
}

针对不定参数的函数,我们可以这样调用

f(1)

f(1, 2)

f(1, 2, 3)

避免了我们在函数里定义一长串变量的情况。

上面的不定参数是int类型的,那么是否支持多种类型混用的不定参数呢?

是可以的,使用...interface{}这种形式

代码语言:javascript
复制
func f(args ...interface{}) {
    for _, arg := range args {
        switch arg.(type) {
            case int:
            	fmt.Println("It is int type")
            case string:
            	fmt.Println("It is string type")
            case int64:
            	fmt.Println("It is int64 type")
        }
    }
}

注意,这里的i.(T)形式不是强制转换或者隐式类型转换,这是类型断言,表示判定类型的。

Go里面是没有隐式类型转换的,不仅没有,而且强制类型转换也很严格。

3、返回值
3.1 返回参数

不同于Java,Go函数是可以支持多返回值的,比如这里返回了ret和err两个参数。

返回值的定义方式也很灵活,可以写成

代码语言:javascript
复制
func f(a int, b int) (int, error) {
    fmt.Println("This is function")
    return
}

如果返回只有一个参数可以写成

代码语言:javascript
复制
func f(a int, b int) (ret int) {
    fmt.Println("This is function")
    return
}

或者

代码语言:javascript
复制
func f(a int, b int) int {
    fmt.Println("This is function")
    return
}
3.2 “_”的用法

在前面的文章,我们也顺带提过,对于函数返回的值,有些我们不关心或者不需要的话,我们不能抹掉他的位置,但是可以使用"_"来表示这个参数的存在,只是不用而已,比如这样调用上面的函数是不行的

代码语言:javascript
复制
ret := f(1, 2)	// 缺少err返回值

但是这样是OK的

代码语言:javascript
复制
ret, _ := f(1, 2)

或者这样

代码语言:javascript
复制
_, err := f(1, 2)	
3.3 error

error接口是Go标准库为了错误处理提供的接口。

一般在业务代码中,我们会调用某个方法后,判定方法对应的值是否为nil判定方法是否被正常执行

代码语言:javascript
复制
if err != nil {
    // 没有正常执行
} else {
    // 正常执行
}
3.4 panic和recover和defer

说到error,正好说说panic()和recover()两个函数

当我们遇到一些err的时候,我们可能就会直接抛出panic,这里的panic可以近似理解为Java里面的Exception,即抛出异常。

代码语言:javascript
复制
if err != nil {
    panic(err)
}

一旦抛出panic,则程序将会终止,除非遇到一种情况,即有recover的存在。

说到recover则不得不提defer

defer是Go里面的新特性,有点类型Java里面的finally,承担回收资源或者解锁这类的收尾工作,但是比finally要灵活,Go函数的defer可以放在函数的任意位置,不管函数是否正常执行,在跳出函数前都会执行defer定义的函数。

接着说recover,如果在函数抛出panic,只要在最后遇到recover也是可以恢复正常的,形式如下

代码语言:javascript
复制
defer func() {
    if ret := recover(); ret != nil {
        fmt.Println("Catch Runtime Error:)
    }
}

4、其他

4.1 说说func

每个函数都以func开始,来表明自己是一个函数。

那么学过Java的肯定会问,没有像public、private这样的访问修饰符吗?

没有,但是Go通过另外一种规则实现了访问范围即可见性。对于函数名使用大写字母开头,则表示可以被其他包使用,如果使用小写字母开头,则只能本包内使用。

当然,这个规则,也适用于变量的声明。

4.2 匿名函数

和Java等其他语言一样,Go函数也有匿名函数。

代码语言:javascript
复制
func (a, b int, s string) int {
    ...
}

可以通过直接在后面赋值的方式直接执行

代码语言:javascript
复制
func (a, b int, s string) int {
    ...
}(1, 2, "test")

这里主要从Go语言的函数构成包括关键字func,入参和返回值介绍Go函数的一些特性。当然了,Go函数还有很多灵活性就不再一一阐述了,有待你我在业务项目中慢慢实践体会了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-06-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、Go语言中的函数长啥样
  • 2、入参
    • 2.1 参数合并声明
      • 2.2 不定参数
        • 3、返回值
          • 3.1 返回参数
            • 3.2 “_”的用法
              • 3.3 error
                • 3.4 panic和recover和defer
                • 4、其他
                  • 4.1 说说func
                    • 4.2 匿名函数
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档