iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
Modern Web

還喝不 go系列 第 7

[13th][Day7] func -1

不定長度參數 Variadic Functions
Golang 中,有些函式的參數長度是不固定的,像是 fmt 套件的 Printf 及 Sprintf 函式,這兩個函式,第一個參數是做為模板的字串,第二個以後的參數就是我們要填入的值,而值的數量是不固定的
這是由於 Go 支援 不定長度參數這個強大的東東

package main
 
import (
    "log"
)
 
func sum(args ...int) int {
    sum := 0.0
 
    for _, e := range args {
        sum += e
    }
 
    return sum
}
 
func main() {
    s := sum(1, 2, 3, 4, 5)
 
    fmt.Println(s)
}

輸出為 15


    s1 := sum(1, 2)
    s2 := sum(1, 2, 5)
    s3 := sum(9, 4, 8, 7)
    s4 := sum(1, 0, 4, 8, 5, 7, 6)
    

不定參數傳入函式後,對參數本身來說是一個 slice[],在函式中透過此 slice[] 即可取得個別的參數值。
至於 slice[] 是什麼呢??
簡單來說就是 array ,之後再來詳談

傳值呼叫 vs. 傳址呼叫
如同 C 語言,所有 Go 的函式都是傳值呼叫 (call by value),而這個值有可能是基本型別或指標或其他型別。當我們傳遞指標時,我們會拷貝指標的位址,但不會拷貝指標所指向的值;當值很大時,傳遞指標比傳整個值有效率。

而在實際應用的過程當中
有些變數、方法的操作必須經由 address 才有辦法更改
如 database 的 scan , 或是 json.UnMarshal 的寫入
會看到很多 * & 符號

init
init() 是一個特殊的函式,若程式碼內有 init 會在程式一開始執行的時候呼叫該函式,順序在 main 函式之前。

init()
autoload()
start()
...etc

go 的 func 宣告中常常會看到一堆括號,一堆奇奇怪怪的括號
讓我們來稍微檢視一下

不帶 return

func functionName(name string) {}
func functionName(name1 string, name2 string) {}

匿名函式

func(){
    //do something
}

匿名函式 + 執行

func(){
    //do something
}()

一個 return 值

func functionName(name string) string {}
func functionName(name string) (str string) {}

兩個 return 值

func functionName(x, y int) (int, int) {}

兩個 return 值 + 預先宣告

func functionName(x, y int) (return1 int , return2 int) {}

帶 receiver 的函式

func (v Revicers) receiverFunc() float64 {}
func (v *Revicers) receiverFunc(f float64) {}

一開始看到這些 func 時總是令我覺得非常困惑,但多看幾次會有一點點方向,實際用過後才會了解到底功能在哪

指標接受器 Pointer Receivers
『宣告』的動作定義了程式的各種實體物件以及部分或全部的屬性 Go 主要有四種類型的宣告語句:

var   變數
const 常數
type  型別
func  函式實體

帶 recevier 的 func 宣告方式如下
recevier 寫在 func 和 method name 之間


type Revicers struct {
	X, Y float64
}

func (v Revicers) SubFunc() float64 {
	return math.Max(v.X, v.Y)
}

func main() {
    a1 := Revicers{28, 25}
	fmt.Println(a1.SubFunc())
}

輸出為 28

(v Revicers) 就是 recevier
這個命名 func (v Revicers) SubFunc() float64 {} 可以解讀為
SubFunc() method 擁有一個「類別為 Revicers 宣告為 v 」的 receiver


上一篇
[13th][Day6] func
下一篇
[13th][Day8] Pointer
系列文
還喝不 go20

尚未有邦友留言

立即登入留言