可變參數(shù)函數(shù)的更好替代方案有:使用切片作為參數(shù)使用結(jié)構(gòu)體作為參數(shù)使用函數(shù)柯里化
Go 可變參數(shù)的更好替代方案
Go 中的可變參數(shù)函數(shù)通過(guò) ... 語(yǔ)法允許傳遞任意數(shù)量的參數(shù)。雖然這在某些情況下很方便,但也有其局限性,包括:
類(lèi)型不安全: 可變參數(shù)函數(shù)的參數(shù)沒(méi)有明確的類(lèi)型,這可能會(huì)導(dǎo)致類(lèi)型檢查器無(wú)法檢測(cè)到錯(cuò)誤。
效率低下: 可變參數(shù)函數(shù)內(nèi)部通常使用切片,這會(huì)帶來(lái)額外的內(nèi)存分配和復(fù)制開(kāi)銷(xiāo)。
替代方案
有幾種替代方案可以替代可變參數(shù)函數(shù):
1. 使用切片作為參數(shù):
func max(numbers []int) int {
if len(numbers) == 0 {
return 0
}
max := numbers[0]
for _, n := range numbers {
if n > max {
max = n
}
}
return max
}
登錄后復(fù)制
2. 使用 structs 作為參數(shù):
type Stats struct {
Mean float64
Median float64
Mode float64
}
func calcStats(nums []float64) Stats {
// ... 計(jì)算統(tǒng)計(jì)數(shù)據(jù)并填充 `Stats` struct
return Stats{
Mean: mean,
Median: median,
Mode: mode,
}
}
登錄后復(fù)制
3. 使用函數(shù)柯里化:
柯里化將一個(gè)多參數(shù)函數(shù)轉(zhuǎn)換為一個(gè)一系列單參數(shù)函數(shù)的過(guò)程。例如,我們可以對(duì) max 函數(shù)進(jìn)行柯里化:
func maxCurried(ns ...int) int {
return func(n int) int {
if n > ns[0] {
ns[0] = n
}
return ns[0]
}
}
登錄后復(fù)制
實(shí)戰(zhàn)案例
假設(shè)我們有一個(gè)函數(shù)需要計(jì)算一系列整數(shù)的最大值,我們來(lái)比較一下使用可變參數(shù)函數(shù)和切片函數(shù)的效率:
package main
import (
"fmt"
"time"
)
func maxVarargs(nums ...int) int {
if len(nums) == 0 {
return 0
}
max := nums[0]
for _, n := range nums {
if n > max {
max = n
}
}
return max
}
func maxSlice(nums []int) int {
if len(nums) == 0 {
return 0
}
max := nums[0]
for _, n := range nums {
if n > max {
max = n
}
}
return max
}
func main() {
// 產(chǎn)生一個(gè)包含 100 萬(wàn)個(gè)隨機(jī)整數(shù)的切片
nums := make([]int, 1000000)
for i := range nums {
nums[i] = rand.Int()
}
// 使用可變參數(shù)函數(shù)計(jì)算最大值
start := time.Now()
maxVarargs(nums...)
elapsedVarargs := time.Since(start)
// 使用切片函數(shù)計(jì)算最大值
start = time.Now()
maxSlice(nums)
elapsedSlice := time.Since(start)
fmt.Println("MaxVarargs execution time:", elapsedVarargs)
fmt.Println("MaxSlice execution time:", elapsedSlice)
}
登錄后復(fù)制
運(yùn)行此程序,我們將看到切片函數(shù)明顯比可變參數(shù)函數(shù)快得多。






