• Go通关05:函数和方法的不同之处!


    函数

    函数声明

    func funcName(params) result {
      body
    }
    
    • 关键字 func 用于声明一个函数
    • funcName 函数名
    • params 函数的参数
    • result 是函数的返回值,可以返回多个返回值,如果没有可以省略。
    • body 函数体

    示例
    1.

    • a、b形参类型一致,可以省略其中一个类型的声明
    func sum (a, b int) {
      return a + b
    }
    

    2.多值返回

    • 返回值的部分类型定义需要小括号括起来。
    func sum (a, b int) (int,error) {
      if a <0 || b <0 {
        return 0, errors.New("a或b不能是负数")
      }
      return a + b, nil
    }
    

    3.命名参数返回

    • 函数中给命名返回参数赋值,相当于函数有了返回值,所以可以忽略 return 后要返回的值了。
    func sum (a, b int) (sum int,err error) {
      if a <0 || b <0 {
        return 0, errors.New("a或b不能是负数")
      }
      sum = a + b
      err = nil
      return
    }
    

    4.可变参数

    • 函数的参数是可变的
    • 定义可变参数,只要在参数类型前加三个点 ... 即可
    • 可变参数的类型其实就是切片,下面示例中 params 的参数类型是 []int
    func sum(params ...int) int {
        sum := 0
        for _, i := range params {
            sum += i
        }
        return sum
    }
    

    包级函数

    • 函数都会从属于一个包,我们自定义的函数属于 main 包。Println 函数属于 fmt 包。
    • 想要调用其他包内的函数,那么那个函数名称首字母要大写,使其作用域变为公有的。
    • 函数首字母小写,只能在同一个包中被调用

    匿名函数和闭包

    匿名函数就是没有名称的函数。

    func main(){
      //注意,sum 只是一个函数类型的变量,不是函数名字
      sum := func(a, b int) int {
        return a + b
      }
      fmt.Println(sum(1, 2))  // 3
    }
    

    匿名函数可以在函数中进行嵌套,这个匿名函数称为内部函数,内部函数可以使用外部函数的变量,这种方式就是闭包。

    func main (){
      sm := sum()
      fmt.Println(sum())
      fmt.Println(sum())
      fmt.Println(sum())
    }
    
    func sum () func() int{
      i := 0
      return func ()int{
        i++
        return i
      }
    }
    
    //结果为:
    1
    2
    3
    

    由于闭包函数,sum 函数返回一个匿名函数,匿名函数持有外部函数 sum 的变量 i,所以在main函数中,每次调用 sum(),i的值就会 +1。

    在 Go 语言中,函数也是一种类型,可以作为函数类型的变量、参数、或者一个函数的返回值。

    方法

    方法和函数类似,不同之处就是方法必须有一个接收者,这个接收者是一个“类”(类型),这样这个方法就算属于这个“类”。

    type Name string
    func (n Name)String(){
      fmt.Println("name is ", n)
    }
    
    • 示例中 String() 就是 Name 这个类型的方法
    • 接收者需要加在 func 和方法名之间,使用()
    • 接收者: (变量,类型)

    使用:

    func main(){
      name := Name("无尘")
      name.String()
    }
    //出处
    name is 无尘
    

    值类型接收者、指针类型接收者

    方法的接收者可以使用值类型(例如上面示例)或者指针类型。
    如果接收者是指针,那么对指针的修改是有效的:

    func (n *Name) Modify(){
      *n = Name("wucs")
    }
    
    func main(){
      name := Name("无尘")
      name.String()
      name.Modify()
      name.String()
    }
    
    //输出
    name is  无尘
    name is  wucs
    

    注意:在调用方法时,传递的接收者实质上都是副本,只不过一个是值副本,一个是指向这个值的指针的副本。指针指向原有值,所以修改指针指向的值,也就修改了原有值。
    方法的调用者,可以是值,也可以是指针((&name).Modify()),Go 语言会自动转义,我们无需关心。

    方法表达式

    方法可以赋值给变量

    name := Name("无尘")
    //方法赋值给变量,方法表达式
    n = Name.String
    //要传一个接收者name进行调用
    n(name)
    

    无论方法是否有参数,通过方法表达式调用,第一个参数必须是接收者,然后才是方法自身的参数。

  • 相关阅读:
    element-UI树形table父子级全选
    VUE父组件调用子组件方法
    elementUI-radio(单选框)label数据类型问题
    微信小程序下载wod,exc,pdf,并显示进度条
    微信小程序js跳转到外部页面
    微信使用e-char图表采坑
    微信登录授权
    外部二维码进入小程序
    js将对象属性作为参数传递
    vscode 个人配置
  • 原文地址:https://www.cnblogs.com/isungge/p/15098044.html
Copyright © 2020-2023  润新知