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自動轉成指針調用
相關文章
相關標籤/搜索