iT邦幫忙

0

Golang 每日一小時(Day4)

go
  • 分享至 

  • xImage
  •  

上次學完 for loop,這次接著官方教學往後看,第一個是 switch,switch 倒是沒有太大區別,值得一提的是不用 break,也可以不用條件式 (視為 true):

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("Good morning!")
	case t.Hour() < 17:
		fmt.Println("Good afternoon.")
	default:
		fmt.Println("Good evening.")
	}
}

後面的 defer 就很有意思了,根據官方說法:

A defer statement defers the execution of a function until the surrounding function returns.

一開始以為是所在的 function 結束後執行 defer 後面的動作,但試了一下並不是,精確地來說是「 function return 前執行」。

那這兩種有什麼區別?
後者可以透過 defer 更改 function return 的值,前者就完全辦不到了...

例如這個 function,最終回傳的是 2:

func Test() (x int) {
    defer func() {
        x++
    }()
    return 1
}

並且 defer 是以 stack(LIFO) 儲存,後加入的會先做

defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)

3
2
1

接著就出現了有趣的事,本來想複習一下各種 function 的寫法,意外發生了。

func Test() int {
	x := 1
	defer func() {
		x++
	}()
	return x
}

原本以為這東西跟上面一樣會回傳 2,結果是回傳 1...
一瞬間腦袋蹦出了好幾個問號????
難道 Named Return Value 跟普通變數的行為是不同的嗎????

邊查邊跟 GPT 討論,發現這牽扯到 Go 的行為,口語上似乎會叫成 "return slot"(GPT 講的),雖然用這個詞查不到這個行為,不過就先這樣了,我只想搞懂行為本身...

若當前這個 function 沒有 Named Return Value,Go 在執行時,會有「隱藏的變數用來預先存放」要 return 的值,所以假設 function 長這樣:

func Test() int {
	x := 1
	defer func() {
		x++
	}()
	return x
}

實際上 return 的並不是 x,而是值跟 x 一樣的另一個變數,可能是 y, z...bruh bruh

但若 function 有 Named Return Value,這個 Named Return Value 就會直接是核心用來存放的那個變數,所以 defer 在操作時會確實操作到核心準備 return 的變數,也就可以變更 return 的值了!

終於是摸到了一些 Go 的語言特性之一,感覺光 defer 就可以變出好多花樣,不過學完 defer 腦袋也昏昏的了,今天就先這樣好了...


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言