Go篇|函数和方法

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

函数

函数声明

// 声明一个函数
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 声明一个函数闭包

  • 函数名函数

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

    • 多个参数的类型都一致,可统一块儿来spa

    • 容许参数的数量可变,便可变参数。可变参数的类型就是切片指针

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

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

包级函数

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

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

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

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

匿名函数和闭包

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

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

方法

函数和方法区别

方法和函数很类似,最大不一样:方法必需要有一个接收者get

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

因此,函数属于一个包,方法属于一个类型

// 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自动转成指针调用
相关文章
相关标签/搜索