# Day11 Go加油-韓式寒士函式(func) 今天邁入Go的函式啦 ## 函式 函式`func`是聰明人為了不想重複打一樣的Code才寫的。 函式效能,因為要進出、攜帶傳入值、返回值,效能不佳,但講究的是重複利用性、可讀性。 可讀性佳跟效能快在某些方面是背道而馳的,例如:機器碼效能一級棒,但可讀性零。 但在2020這個手機就是`20世紀超級電腦`的年代很少人在Care了這一點點消耗了,架構、演算法還看得更重要。 Go語言`func`命名是採用`駝峰式大小寫`,譬如:`HowDoYouTurnThisOn` 。 字首大寫代表`對外暴露`,字首小寫代表`此func`只能在`相同的Package`中才能使用。 沒錯。 我們所熟悉的`main` 就是一個`func`,所有程式的進入點。 Go語言中函式有許多種方式可以應用,我把它拆分來成`好多型`,語法會混搭著用, 來看看以下簡單的`func`範例: ### 【func】型1:沒有回傳值 沒有回傳任何東西的func > **func Variable() { > ... > }** > >> func a() { >> ... >> } ```go func a() { fmt.Println("Hello") } func main() { a() } /* result: Hello */ ``` 主程式直接call就能印出了 ### 【func】型2:有回傳值 回傳一個變數,要先定義回傳的變數型態 > **func Variable() ReturnType { > ... > }** > >> func b() string { >> return ... >> } ```go func b() string { return "Hi" } func c() int { return 1 + 5 } func main() { b := b() fmt.Println(b) fmt.Println(c() + 6) } /* result: Hi 12 */ ``` https://play.golang.org/p/GHVtD8oNm2J ### 【func】型3:有回傳值且預先宣告變數名稱 > **func Variable() (Variable ReturnType) { > ... > }** >> func d() (e string) { >> ... >> return >> } ```go func d() (e string) { e = "I am e!" return e } ``` 這行為等於是在`func`頭裡面就做了 `var e string` 這件事 所以函式內的`e`可以直接取用。 有預先宣告變數的話,`Go`有100%的信心知道你要回傳變數`e`, **所以就算把`return e` 只寫成`return`也可以智能的回傳。** ### 【func】型4:多個回傳值 > **func Variable() (ReturnType, ReturnType) { > ... > }** >> func f() (int, int) { >> return ... >> } ```go func f() (int, int) { return 1 + 1, 2 + 2 } func main() { x, y := f() fmt.Println(x, y) } /* result: 2 4 */ ``` https://play.golang.org/p/6L9hkyluXR_e 現在應該知道多個回傳值、又預先宣告變數名稱該怎麼做了吧 https://play.golang.org/p/Al_5IeRtrxw --- 以上都是`func`比較基礎的功能,頗酷、也挺簡便好用。 往下會講進階用法 --- ### 【func】型999 func 還能回傳 func ### 【func】型SSR: Struct中的Func Go有這個用法,超酷~~ Struct搭配Func,就像`變形金鋼鐵人者哈特利波特斯拉線圈` > 首先要先宣告一個Struct, > 再來才是以下的Func > > **func (S *Struct) Variable() { > ... > }** >> func (CIS *Programmer) ask() { >> ... >> } ```go type Programmer struct { Question string } func (CIS *Programmer) Ask() { question := CIS.Question fmt.Println(question) } ``` 這方法讓你的物件`Programmer` `動`了起來, 他不只是個物件了,他現在會`ask`問可不可以休息 ```go func main() { var I Programmer I.Question = "Hey, Can I Sleep?" I.Ask() } /* result: Hey, Can I Sleep? */ ``` > 很遺憾的,雖然工程師很累很想睡覺,但收到的回應通常是`No` > 你可以再做一個`Boss`物件,`Boss.Reply()`來回答`No`。 https://play.golang.org/p/iH3orZt1HDG ### 【func】型★★★★★★★★★★ go func 併發指令簡單好記 詳見[**Day14 Go併發症狀**](https://ithelp.ithome.com.tw/articles/10240892) ### 【func】型-【第零式】: 你聽過回調函式(Callback Function)嗎?