1. 程式人生 > >JAVA轉go系列之 函式

JAVA轉go系列之 函式

函式是程式的基本程式碼塊,函式是解決一類問題的步驟的有序組合,java和go都類似 需要提供一個函式入口 也就是main函式

java程式裡面函式被稱之為方法,一般情況下定義一個方法包含以下語法

修飾符 返回值型別 方法名(引數型別 引數名){方法體   return 返回值}

修飾符:修飾符是可以選擇的,告訴編譯器該如何呼叫該方法,定義了該方法的訪問許可權

返回值型別:有些方法需要有返回值,需要返回值的方法必須明確指定返回值的型別,沒有返回值則用void關鍵字宣告

方法名:是方法的實際名稱,方法名稱和引數列表共同構成方法簽名

引數型別,引數就像是一個佔位符,傳遞值給引數,這個值被稱為實參或變數。引數列表指的是方法的引數型別,順序和引數的個數,引數是可以選擇的可以一個引數都沒有

方法體:方法體包含具體的語句,定義了該方法的功能

Go語言函式

函式格式定義如下:

func function_name( [parameter list] ) [return_types] {
   函式體
}

在Go語言裡面方法都被稱之為函式,函式由func關鍵字宣告,後面跟著方法的名稱,引數列表,最後是返回值型別,注意:go裡面的函式允許有多個返回值,在java中我們的方法只允許有一個返回值,當有多個返回值的時候我們一般會封裝到一個數據型別中返回來,這一點Go就要比java方便多了,當我們需要返回多個引數的時候可以直接返回不需要去另外維護一個數據型別來返回

  • func:函式由 func 開始宣告
  • function_name:函式名稱,函式名和引數列表一起構成了函式簽名。
  • parameter list:引數列表,引數就像一個佔位符,當函式被呼叫時,你可以將值傳遞給引數,這個值被稱為實際引數。引數列表指定的是引數型別、順序、及引數個數。引數是可選的,也就是說函式也可以不包含引數。
  • return_types:返回型別,函式返回一列值。return_types 是該列值的資料型別。有些功能不需要返回值,這種情況下 return_types 不是必須的。
  • 函式體:函式定義的程式碼集合。
  • 例項

    以下例項為 max() 函式的程式碼,該函式傳入兩個整型引數 num1 和 num2,並返回這兩個引數的最大值:

    /* 函式返回兩個數的最大值 */
    func max(num1, num2 int) int {
       /* 宣告區域性變數 */
       var result int
    
       if (num1 > num2) {
          result = num1
       } else {
          result = num2
       }
       return result 
    }

函式引數

函式如果使用了引數,該變數可以稱之為函式的形參這個和java類似,形參就像定義在函式體內的區域性變數

呼叫函式,可以通過兩種方式來傳遞引數

值傳遞:值傳遞是指呼叫函式時將實際引數複製一份傳遞到函式中,這樣在函式中如果對引數的修改將不會影響到實際的引數

引用傳遞:引用傳遞是指在呼叫函式時將實際引數的地址傳遞到函式當中,那麼在函式中對引數的修改將會影響到實際引數

其實這兩個傳參和java差不多,只不過在java中 基礎資料型別預設是使用的值傳遞,而引用型別使用的是地址傳遞,在Go語言中預設都是值傳遞,如果需要使用值傳遞則需要用*顯示的宣告

Go 語言函式閉包

Go語言支援匿名函式,可以作為閉包。匿名函式是一個內聯語句或者表示式,匿名函式的優越性在於可以直接使用函式內的變數,不必申明。看下例項

package main

import "fmt"

func getSequence() func() int {
   i:=0
   return func() int {
      i+=1
     return i  
   }
}

func main(){
   /* nextNumber 為一個函式,函式 i 為 0 */
   nextNumber := getSequence()  

   /* 呼叫 nextNumber 函式,i 變數自增 1 並返回 */
   fmt.Println(nextNumber())
   fmt.Println(nextNumber())
   fmt.Println(nextNumber())
   
   /* 建立新的函式 nextNumber1,並檢視結果 */
   nextNumber1 := getSequence()  
   fmt.Println(nextNumber1())
   fmt.Println(nextNumber1())
}

//實際輸出結果 1 2 3

這個例子困擾我半天,go語言預設是值傳遞,沒有顯示的宣告就因該是值在傳遞應當不會影響到原來的值

後來經過同事的開解,我們可以這樣理解,吧getSequence理解成一個java的一個類,i理解成java的一個全域性變數

我們呼叫getSequence()返回的是這個類的物件,後面的操作都是對物件裡面的值在操作。