关于goland:GO语言入门-六函数和方法

41次阅读

共计 2807 个字符,预计需要花费 8 分钟才能阅读完成。

是时候开始钻研函数和办法了。。。

函数

通过函数,能够把开发工作分解成一个个小的单元,这些小单元能够被其余单元复用,进而进步开发效率、升高代码重合度。

1. 函数申明

func funcName(params) result {body}
  • 关键字 func
  • 函数名字 funcName
  • 函数的参数 params,用来定义形参的变量名和类型
  • result 是返回的函数值,用于定义返回值的类型,如果没有能够省略
  • body 就是函数体,能够在这里写函数的代码逻辑

写一个计算两数相加的函数:

package main

import ("fmt")

// 计算两值之和
// 变量名称在前,变量类型在后
// 变量名称叫做参数名称,也就是函数的形参
func addTwoNum(a int, b int) int{return a + b}

func main(){fmt.Println(addTwoNum(12, 21))
}

运行后果为:

2. 多值返回

Go 语言的函数能够返回多个值,也就是多值返回
第一个值返回函数的后果,第二个值返回函数出错的信息

package main

import (
    "errors"
    "fmt"
)

// 计算两值之和,如果为正数就返回谬误
func addTwoNum(a int, b int) (int, error) {
    if a < 0 || b < 0 {return 0, errors.New("a 或者 b 不能为正数")
    }
    return a + b, nil
}

func main() {
    // 获取后果和错误信息
    a, err := addTwoNum(-12, 21)
    if err != nil {fmt.Println(err)
    } else {fmt.Println("计算结果为:", a)
    }
}

运行后果为:

3. 命名返回参数

函数的返回值也能够有变量名称,这个并不罕用,理解一下
革新函数为:

package main

import (
    "errors"
    "fmt"
)

// 计算两值之和,如果为正数就返回谬误
func addTwoNum(a int, b int) (sum int, err error) {
    if a < 0 || b < 0 {
        // 这里依照失常进行返回
        return 0, errors.New("a 或者 b 不能为正数")
    }
    // 这里依照返回值给相干参数赋值,return 前面不须要任何参数
    sum = a + b
    err = nil
    return
}

func main() {
    // 获取后果和错误信息
    a, err := addTwoNum(-12, 21)
    if err != nil {fmt.Println(err)
    } else {fmt.Println("计算结果为:", a)
    }
}

运行后果为:

4. 可变参数

可变参数,就是函数的参数数量是可变的
如果函数中既有一般参数又有可变参数,那么可变参数肯定要放到参数列表的开端
次要就是在参数类型后面增加三个点
例如:

// 没有参数
fmt.Println()
// 一个参数
fmt.Println("zhouzhaodong")
// 两个参数
fmt.Println("zhouzhaodong","xiaoqiang")

咱们写一个计算所有数字之和的函数:

package main

import ("fmt")

// 计算所有值之和
func addAllNum(params ...int) int {
    sum := 0
    for _, i := range params {sum += i}
    return sum
}

func main() {fmt.Println("计算结果为:", addAllNum(1, 2, 3, 3, 3, 4, 5, 9))
}

运行后果为:

5. 包级函数

不论是自定义的函数
还是咱们应用到的函数,都会隶属一个包
也就是 package
不同包的函数要被调用,那么函数的作用域必须是私有的,也就是 函数名称的首字母要大写

  • 函数名称首字母小写代表公有函数,只有在同一个包中才能够被调用
  • 函数名称首字母大写代表私有函数,不同的包也能够调用
  • 任何一个函数都会从属于一个包

6. 匿名函数和闭包

匿名函数就是没有名字的函数

package main

import ("fmt")

func main() {sum := func(a, b int) int {return a + b}
    fmt.Println("计算结果为:", sum(1, 2))
}

运行后果为:

在函数中 再定义函数 (函数嵌套),定义的这个匿名函数,也能够称为 外部函数
更重要的是,在函数内定义的外部函数,能够应用内部函数的变量等,这种形式也称为 闭包

办法

办法必须要有一个 接收者 ,这个接收者是一个类型
这样办法就和这个类型绑定在一起,成为 这个类型的办法

接收者的定义和一般变量、函数参数等一样
后面是变量名,前面是接收者类型

package main

import ("fmt")

// 定义一个新的类型,该类型等价于 uint
// 能够了解为 uint 的重命名
type Age uint

// 定义一个办法,参数就是 Age
func (age Age) String() {fmt.Println("the age is", age)
}

func main() {age := Age(25)
    age.String()}

运行后果为:

接收者就是函数和办法最大的不同

1. 值类型接收者和指针类型接收者

定义的办法的接收者类型是指针,所以咱们对指针的批改是无效的,如果不是指针,批改就没有成果,如下所示:

package main

import ("fmt")

// 定义一个新的类型,该类型等价于 uint
// 能够了解为 uint 的重命名
type Age uint

// 定义一个办法,参数就是 Age
func (age Age) String() {fmt.Println("the age is", age)
}

// 定义一个办法,参数就是 Age 指针
func (age *Age) Modify() {*age = Age(30)
}

func main() {age := Age(25)
    age.String()
    // 批改 age 的值
    age.Modify()
    age.String()}

运行后果为:

提醒:在调用办法的时候,传递的接收者实质上都是正本,只不过一个是这个值正本,一是指向这个值指针的正本。指针具备指向原有值的个性,所以批改了指针指向的值,也就批改了原有的值。咱们能够简略地了解为值接收者应用的是值的副原本调用办法,而指针接收者应用理论的值来调用办法。

这就是 Go 语言编译器帮咱们主动做的事件:

  • 如果应用一个值类型变量调用指针类型接收者的办法,Go 语言编译器会主动帮咱们取指针调用,以满足指针接收者的要求。
  • 如果应用一个指针类型变量调用值类型接收者的办法,Go 语言编译器会主动帮咱们解援用调用,以满足值类型接收者的要求。

总之,办法的调用者,既能够是值也能够是指针,不必太关注这些,Go 语言会帮咱们主动本义,大大提高开发效率,同时防止因不小心造成的 Bug。

不论是应用值类型接收者,还是指针类型接收者,要先确定你的需要:在对类型进行操作的时候是要扭转以后接收者的值,还是要创立一个新值进行返回?这些就能够决定应用哪种接收者。

集体博客地址:

http://www.zhouzhaodong.xyz/

正文完
 0