---
# System prepended metadata

title: Day11 Go加油-韓式寒士函式(func)

---

# Day11 Go加油-韓式寒士函式(func)

今天邁入Go的函式啦  
## 函式
函式`func`是聰明人為了不想重複打一樣的Code才寫的。  
函式效能，因為要進出、攜帶傳入值、返回值，效能不佳，但講究的是重複利用性、可讀性。  
可讀性佳跟效能快在某些方面是背道而馳的，例如：機器碼效能一級棒，但可讀性零。  
但在2020這個手機就是`20世紀超級電腦`的年代很少人在Care了這一點點消耗了，架構、演算法還看得更重要。  

Go語言`func`命名是採用`駝峰式大小寫`，譬如：`HowDoYouTurnThisOn` 。  
字首大寫代表`對外暴露`，字首小寫代表`此func`只能在`相同的Package`中才能使用。  

沒錯。
我們所熟悉的`main` 就是一個`func`，所有程式的進入點。  

Go語言中函式有許多種方式可以應用，我把它拆分來成`好多型`，語法會混搭著用，  
來看看以下簡單的`func`範例：   


### 【func】型１：沒有回傳值  

沒有回傳任何東西的func  

> **func Variable() {
> ...
> }**
>
>> func a() {
>> ...
>> }


```go
func a() {
fmt.Println("Hello")
}

func main() {
	a()
}
/* result:
Hello
*/
```
主程式直接call就能印出了

### 【func】型２：有回傳值  
回傳一個變數，要先定義回傳的變數型態  

> **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】型３：有回傳值且預先宣告變數名稱  

> **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】型４：多個回傳值

> **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】型９９９
func 還能回傳 func  

### 【func】型ＳＳＲ： 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）嗎？  

