iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
Modern Web

就是個Go,我也可以啦!GOGO系列 第 11

2023鐵人賽 Day 11 Go x 我們應該要把函數當成一等公民

  • 分享至 

  • xImage
  •  

本質上,我們可以說,Go就是一組函數的組合,若看前幾篇我介紹的Go x 方法,會發現Go有以下特點

  • func key word 開頭
  • 可以有多個return value
  • 支持有名稱的return value
  • 支持defer

什麼是 "一等公民"

Go 是為了滿足當代軟體開發的需求而設計的,特別是在併發和多核硬體上,但Go沒有其他語言的類別繼承系統,在go語言,函數是一個唯一一種基於特定輸入,實現特定任務並反饋任務執行結果的block

我們來看“一等公民”的定義

一級函式(first-class function;第一級函數)是指在程序設計語言中,函數被當作頭等公民。這意味著,函數可以作為別的函數的參數、函數的返回值,賦值給變量或存儲在資料結構中。

那...Go何出狂言呢,我們來看Go能做到什麼

  1. 一般建立函數

    func printArray(a []string) {
       appendList := append(a, "end of list")
       fmt.Println(appendList)
    }
    
  2. 在函數內定義函數

    func printArray(a []string) {
       appendList := func(s string, a []string) []string {
         return append(a, s)
       }
       fmt.Println(appendList("end of list", a))
    }
    
  3. 作為類型

     package main
    
     import (
       "fmt"
     )
    
     // 定義一個函數型別,該函數接受一個 string 和一個 string 切片,返回一個 string 切片
     type HandleAppendList func(string, []string) []string
    
     func printArray(a []string, handler HandleAppendList) {
       fmt.Println(handler("end of list", a))
     }
    
     func main() {
       var example = []string{"a", "b", "c"}
    
       // 定義一個符合 HandleAppendList 型別簽名的函數
       appendList := func(s string, a []string) []string {
         return append(a, s)
       }
    
       printArray(example, appendList)
     }
    
    
  4. 作為參數傳入變數內

    func printArray(a []string, f func(s string, a []string) []string) []string {
       return f("end of list", a)
     }
    
     func main() {
       var example = []string{"a", "b", "c"}
    
       appendList := func(s string, a []string) []string {
         return append(a, s)
       }
    
       printArray(example, appendList)
     }
    
    
  5. 作為return value

    package main
    
    import (
      "fmt"
    )
    
    // AppendSuffix 會返回一個將指定後綴加到每個切片元素的函數
    func AppendSuffix(suffix string) func([]string) []string {
      return func(items []string) []string {
        for i, item := range items {
          items[i] = item + suffix
        }
        return items
      }
    }
    
    func main() {
      var example = []string{"a", "b", "c"}
    
      // 獲取一個能將 "-demo" 後綴加到每個元素的函數
      addDemoSuffix := AppendSuffix("-demo")
    
      // 使用該函數
      newExample := addDemoSuffix(example)
      fmt.Println(newExample) // Output: [a-demo b-demo c-demo]
    }
    
    

從上面的例子來看,go的func自由度真的很高,他有其他資料結構的特性,連參數都可以傳遞函數,所以我們才說,在go中,函數式一等公民

functional programing

go的函數作為一等公民讓我們可以做到更多的事情,雖然go並不推崇函數式程式設計,但有些方法可以讓我們寫得更加的優雅

柯里化

柯里化(英語:Currying),又譯為卡瑞化或加里化,是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,並且返回接受餘下的參數而且返回結果的新函數的技

來舉一個go的

package main

import (
	"fmt"
)

// 返回一個函數,這個函數接受b並返回另一個接受c的函數
func addA(a int) func(int) func(int) int {
	return func(b int) func(int) int {
		return func(c int) int {
			return a + b + c
		}
	}
}

func main() {
	// 使用柯里化的方式計算 1 + 2 + 3
	result := addA(1)(2)(3)
	fmt.Println(result) // Output: 6
}


上一篇
2023鐵人賽Day 10 Go的資料結構-slice
下一篇
2023鐵人賽Day 12 Go的資料結構-map
系列文
就是個Go,我也可以啦!GOGO30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言