Skip to Content
Go Realm v1 is released 🎉
TopicsVariadic Function

Go Variadic Function

Variadic function āĻšāϞ⧋ āĻāĻŽāύ āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ āϝāĻž āϝ⧇āϕ⧋āύ⧋ āϏāĻ‚āĻ–ā§āϝāĻ• argument āύāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤

đŸ§ē āĻ…ā§āϝāĻžāύāĻžāϞāϜāĻŋ: āĻŦāĻžāϜāĻžāϰ⧇āϰ āĻŦā§āϝāĻžāϗ⧇āϰ āĻŽāϤ⧋ — āĻāĻ•āϟāĻž, āĻĻ⧁āĻŸā§‹, āĻŦāĻž āĻĻāĻļāϟāĻž āϜāĻŋāύāĻŋāϏāĻ“ āϧāϰ⧇āĨ¤ āφāϞāĻžāĻĻāĻž āφāϞāĻžāĻĻāĻž āĻŦā§āϝāĻžāĻ— āϞāĻžāϗ⧇ āύāĻžāĨ¤


ā§§. Syntax 📌

// ↓ āĻāχ ... āĻŽāĻžāύ⧇ "āϝ⧇āϕ⧋āύ⧋ āϏāĻ‚āĻ–ā§āϝāĻ•" func sum(nums ...int) int { total := 0 for _, n := range nums { // āϭ⧇āϤāϰ⧇ nums āĻšāϞ⧋ []int total += n } return total } fmt.Println(sum(1, 2, 3)) // 6 fmt.Println(sum(10, 20)) // 30 fmt.Println(sum()) // 0 — argument āύāĻž āĻĻāĻŋāϞ⧇āĻ“ āϚāϞ⧇

āϏāĻžāϧāĻžāϰāĻŖ āĻĢāĻžāĻ‚āĻļāύ vs Variadic:

// ❌ āϏāĻžāϧāĻžāϰāĻŖ — āĻĒā§āϰāϤāĻŋāϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻžāϰ āϜāĻ¨ā§āϝ āφāϞāĻžāĻĻāĻž āĻĢāĻžāĻ‚āĻļāύ āϞāĻŋāĻ–āϤ⧇ āĻšāĻŦ⧇ func sum2(a, b int) int { return a + b } func sum3(a, b, c int) int { return a + b + c } // ✅ Variadic — āĻāĻ•āϟāĻžāχ āϝāĻĨ⧇āĻˇā§āϟ func sum(nums ...int) int { /* ... */ }

⧍. āϭ⧇āϤāϰ⧇ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇?

...T parameter-āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āϭ⧇āϤāϰ⧇ []T slice āĻšāĻŋāϏ⧇āĻŦ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇āĨ¤

āĻĒāϰāĻŋāĻ¸ā§āĻĨāĻŋāϤāĻŋnums-āĻāϰ āĻ­ā§āϝāĻžāϞ⧁len(nums)
sum(1, 2, 3)[]int{1, 2, 3}3
sum(5)[]int{5}1
sum()[]int{}0

âš ī¸ argument āύāĻž āĻĻāĻŋāϞ⧇ nil āύāϝāĻŧ, empty slice āĻšāϝāĻŧāĨ¤ āϤāĻŦ⧇ len(nums) == 0 āĻĻāĻŋāϝāĻŧ⧇ āĻšā§‡āĻ• āĻ•āϰāĻžāχ āύāĻŋāϰāĻžāĻĒāĻĻāĨ¤


ā§Š. Rules 📌

āύāĻŋāϝāĻŧāĻŽāωāĻĻāĻžāĻšāϰāĻŖ
āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ⧇ āĻļ⧁āϧ⧁ āĻāĻ•āϟāĻŋ variadic parameterfunc f(a ...int, b ...int) — ❌ compile error
āϏāĻŦāϏāĻŽāϝāĻŧ āϏāĻŦāĻžāϰ āĻļ⧇āώ⧇ āĻĨāĻžāĻ•āϤ⧇ āĻšāĻŦ⧇func f(prefix string, vals ...int) — ✅
Variadic parameter-āĻ āĻāĻ•āχ type...int, ...string, ...any
func greet(greeting string, names ...string) { for _, name := range names { fmt.Println(greeting, name) } } greet("Hello", "Rahim", "Karim", "Jamal") // Hello Rahim // Hello Karim // Hello Jamal

ā§Ē. Slice Unpacking — ... āĻ…āĻĒāĻžāϰ⧇āϟāϰ

āφāϗ⧇ āĻĨ⧇āϕ⧇ āϤ⧈āϰāĻŋ slice āĻĒāĻžāϏ āĻ•āϰāϤ⧇ ... āĻĻāĻŋāϝāĻŧ⧇ unpack āĻ•āϰ⧁āύ:

nums := []int{1, 2, 3, 4, 5} sum(nums...) // ✅ slice unpack āĻ•āϰ⧇ āĻĒāĻžāϏ sum(nums) // ❌ compile error — []int āĻĒāĻžāϏ āĻ•āϰāĻž āϝāĻžāĻŦ⧇ āύāĻž āϏāϰāĻžāϏāϰāĻŋ
// Forwarding — āĻāĻ• variadic āĻĨ⧇āϕ⧇ āφāϰ⧇āĻ•āϟāĻžāϝāĻŧ āĻĒāĻžāϏ āĻ•āϰāĻž func logAll(vals ...any) { fmt.Println(vals...) // ✅ unpack āĻ•āϰ⧇ fmt.Println-āĻ āĻĒāĻžāϏ }

ā§Ģ. Stdlib-āĻ Variadic (Real-world Usage)

Go standard library-āϤ⧇ variadic āĻŦā§āϝāĻžāĻĒāĻ•āĻ­āĻžāĻŦ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ:

FunctionSignature
fmt.Printlnfunc Println(a ...any) (n int, err error)
fmt.Sprintffunc Sprintf(format string, a ...any) string
appendfunc append(slice []T, elems ...T) []T
strings.Joinargument āύāϝāĻŧ, āĻ•āĻŋāĻ¨ā§āϤ⧁ variadic wrapper āϏāĻžāϧāĻžāϰāĻŖ
// append — Go-āϰ āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āĻŦ⧇āĻļāĻŋ āĻŦā§āϝāĻŦāĻšā§ƒāϤ variadic function s := []int{1, 2} s = append(s, 3, 4, 5) // ✅ āĻāĻ•āĻžāϧāĻŋāĻ• element s = append(s, other...) // ✅ āφāϰ⧇āĻ•āϟāĻŋ slice unpack āĻ•āϰ⧇

ā§Ŧ. Functional Options Pattern (Production Critical) đŸ”Ĩ

Production Go code-āĻ variadic function-āĻāϰ āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšāϞ⧋ Functional Options PatternāĨ¤ āĻāϟāĻŋ grpc, zap, cobra āϏāĻš āĻĒā§āϰāĻžāϝāĻŧ āϏāĻŦ āĻŦāĻĄāĻŧ library-āϤ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧāĨ¤

type Server struct { host string port int timeout int } type Option func(*Server) func WithPort(port int) Option { return func(s *Server) { s.port = port } } func WithTimeout(t int) Option { return func(s *Server) { s.timeout = t } } // Variadic āĻĻāĻŋāϝāĻŧ⧇ optional config āύ⧇āĻ“āϝāĻŧāĻž āĻšāĻšā§āϛ⧇ func NewServer(host string, opts ...Option) *Server { s := &Server{host: host, port: 8080, timeout: 30} // defaults for _, opt := range opts { opt(s) } return s } // Usage — caller āĻļ⧁āϧ⧁ āϝāĻž āĻĻāϰāĻ•āĻžāϰ āϤāĻžāχ āĻĻ⧇āϝāĻŧ s1 := NewServer("localhost") // āĻļ⧁āϧ⧁ default s2 := NewServer("localhost", WithPort(9090)) // port override s3 := NewServer("localhost", WithPort(9090), WithTimeout(60)) // āĻĻ⧁āĻŸā§‹āχ

āϕ⧇āύ āĻāϟāĻž āĻ­āĻžāϞ⧋? āύāϤ⧁āύ option āϝ⧋āĻ— āĻ•āϰāϞ⧇ existing code āĻ­āĻžāϙ⧇ āύāĻžāĨ¤ NewServer(host, port, timeout, maxConn, ...) āĻāĻ­āĻžāĻŦ⧇ āĻŦāĻžāĻĄāĻŧāϤ⧇ āĻĨāĻžāĻ•āϞ⧇ API āϜāϟāĻŋāϞ āĻšāϝāĻŧāĨ¤


ā§­. any āĻĻāĻŋāϝāĻŧ⧇ Mixed Types

// Go 1.18+ — interface{} āĻāϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤ⧇ 'any' āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ func printAll(vals ...any) { for _, v := range vals { switch v := v.(type) { case int: fmt.Printf("int: %d\n", v) case string: fmt.Printf("string: %s\n", v) default: fmt.Printf("unknown: %T\n", v) } } } printAll(42, "hello", true) // type switch āĻĻāĻŋāϝāĻŧ⧇ handle āĻ•āϰāĻž āĻšāĻšā§āϛ⧇

ā§Ž. Common Mistakes âš ī¸

āϭ⧁āϞāϏāĻŽāĻ¸ā§āϝāĻžāϏāĻŽāĻžāϧāĻžāύ
sum(nums) — slice āϏāϰāĻžāϏāϰāĻŋ āĻĒāĻžāϏcompile errorsum(nums...) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ
empty args āĻšā§‡āĻ• āύāĻž āĻ•āϰāĻžindex out of range panicif len(nums) == 0 āĻĻāĻŋāϝāĻŧ⧇ guard āϰāĻžāϖ⧁āύ
any āĻ unchecked type assertionruntime panictype switch āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ
Variadic parameter āĻĒā§āϰāĻĨāĻŽā§‡ āϰāĻžāĻ–āĻžcompile errorāϏāĻŦāϏāĻŽāϝāĻŧ āϏāĻŦāĻžāϰ āĻļ⧇āώ⧇ āϰāĻžāϖ⧁āύ
// ❌ Unchecked — panic āĻšāĻŦ⧇ āϝāĻĻāĻŋ āϕ⧋āύ⧋ arg āύāĻž āĻĨāĻžāϕ⧇ func first(vals ...int) int { return vals[0] // panic if len == 0 } // ✅ Safe func first(vals ...int) (int, bool) { if len(vals) == 0 { return 0, false } return vals[0], true }

⧝. Interview Cheat Sheet

Q: Variadic function-āĻāϰ āϭ⧇āϤāϰ⧇ parameter-āĻāϰ type āϕ⧀?

...T parameter āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āϭ⧇āϤāϰ⧇ []T slice āĻšāĻŋāϏ⧇āĻŦ⧇ āĻĨāĻžāϕ⧇āĨ¤

Q: Argument āύāĻž āĻĻāĻŋāϞ⧇ āϕ⧀ āĻšāϝāĻŧ?

nil āύāϝāĻŧ, empty slice ([]T{}) āĻšāϝāĻŧāĨ¤ len == 0 āĻšāĻŦ⧇āĨ¤

Q: Slice āϕ⧀āĻ­āĻžāĻŦ⧇ variadic function-āĻ āĻĒāĻžāϏ āĻ•āϰāĻŦ⧇āύ?

func(slice...) — ... āĻĻāĻŋāϝāĻŧ⧇ unpack āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤

Q: āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ⧇ āĻ•āϤāϟāĻŋ variadic parameter āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰ⧇?

āĻŽāĻžāĻ¤ā§āϰ āĻāĻ•āϟāĻŋ, āĻāĻŦāĻ‚ āϏ⧇āϟāĻŋ āϏāĻŦāϏāĻŽāϝāĻŧ āϏāĻŦāĻžāϰ āĻļ⧇āώ parameter āĻšāϤ⧇ āĻšāĻŦ⧇āĨ¤

Q: Production-āĻ variadic function-āĻāϰ āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ use case āϕ⧀?

Functional Options Pattern — optional config āĻ—ā§āϰāĻšāĻŖ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝāĨ¤ grpc.Dial(), zap.New() āĻāĻ­āĻžāĻŦ⧇āχ āĻ•āĻžāϜ āĻ•āϰ⧇āĨ¤

Q: ...any vs āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ type — āϕ⧋āύāϟāĻž āĻ­āĻžāϞ⧋?

āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ type āϏāĻŦāϏāĻŽāϝāĻŧ āĻ­āĻžāϞ⧋ — type safety āĻĨāĻžāϕ⧇āĨ¤ ...any āĻļ⧁āϧ⧁ āϤāĻ–āύāχ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ āϝāĻ–āύ āϏāĻ¤ā§āϝāĻŋāχ mixed types āĻĻāϰāĻ•āĻžāϰ (āϝ⧇āĻŽāύ fmt.Println)āĨ¤