Go篇|函数和方法

这是我参与更文挑战的第4天,活动详情查看: 更文挑战

函数

函数声明

// 声明一个函数
func funcName(params paramType) result {
  // body ...
}

// 多个相同类型的参数
func funcName(p1, p2 paramType) result {
  // body ...
}

// 可变参数的函数声明
func funcName(p1 ...interface{}) result {
  // body ...
}

// 多个返回值
func funcName(p1, p2 paramType) (result1, result2) {
  // body ...
}

// 命名返回参数
func funcName(p1 paramType) (sum int,err error){
  // sum也是函数内部的一个变量
  sum = 1
}
复制代码
  • 使用关键字func 声明一个函数

  • 函数名

  • 函数参数(一个或多个,或没有)

    • 多个参数的类型都一致,可统一起来

    • 允许参数的数量可变,即可变参数。可变参数的类型就是切片

      // 声明可变参数的函数
      func sayHiname ...string{
        for val,_ := range name{
          fmt.Println("hi,",val)
        }
      }
      
      // 使用可变参数的函数
      sayHi("xiaohong","xiaoming")
      
      
      复制代码
  • result是返回的函数值,用于定义返回值类型,支持多个返回值。如果没有返回值则可以不写。

    • 支持多个返回值,使用小括号扩起来。在函数中,return返回多个值使用“,”逗号隔开
    • 接收多个返回值时,如果不需要则可以使用“_”忽略它,如 result, _ = sum(1,2)
    • 命名返回参数,即函数返回值也可以有变量名称,该返回值可以当作变量在函数内使用

包级函数

在Go语言中,函数都会从属一个包(package)。

  • 同一个包内的函数都可以被调用
  • 不同包的函数只有公有的才能被调用

在Go中,没有public、private修饰函数来表示函数的公有,私有,主要通过函数名称的首字母大写来表示函数作用域是公有的

  • 函数首字母小写—> 私有函数,只有同一个包才能调用
  • 函数首字母大写—> 共有函数,不同的包也可以调用

匿名函数和闭包

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

复制代码
  • 匿名函数:即没有函数名称的函数
  • 内部函数:就是在函数中定义匿名函数
  • 在函数内定义的内部函数,可以使用外部函数的变量,这种方式就是闭包

方法

函数和方法区别

方法和函数很相似,最大不同:方法必须要有一个接收者

接收者,是一个类型,方法一定跟某一类型绑定。可以理解成:方法是某一个类型的方法

所以,函数属于一个包,方法属于一个类型

// sayHi 和Name类型绑定
type Name string
func (name Name)sayHi(){
	fmt.Println("name is ",name)
}

// 绑定后可以通过.方式使用
name := Name("jasen")
name.sayHi()
复制代码
  • 通过关键字type,声明一个Name类型
  • 方法和类型的绑定主要是通过在方法名sayHi加一个接收者(name Name)
  • 定义接收者的方法后可以通过“.”方式使用

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

// 绑定指针类型接收者
func (name *Name) updateName() {
	*name = Name("yang")
}
//绑定值类型接收者
func (name Name) updateName2() {
	name = Name("yang2")
}

func main() {
	name := Name("jasen")
	name.sayHi()

	name.updateName2()
	name.sayHi()
  
	name.updateName()
	name.sayHi()
}

//输出结果
name is  jasen
name is  jasen
name is  yang
复制代码

观察结果可以发现,基于值类型接收者,修改值不会对原有的值有影响,但是指针类型的接收者会改变原有的值

上述例子,我们使用的是值类型变量去调用方法,如果换成指针类型呢,如(&name).updateName(),可以执行下代码看看结果。

实际结论:

  • 指针类型变量调用值类型接收者的方法,GO会自动转成值调用
  • 值类型变量调用指针接收者的方法,Go自动转成指针调用
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享