Alanlarına varsayılan değerleri olan/olmayan bir nesneyi geri veren bir işleve sahip olduğunuzu varsayın. Bir kurucu (constructor) gibidir. Nesne örneğini ilk oluşturduğunuzda varsayılan değerleri geçersiz kılmak istiyorsanız ne olur? İşlevsel Seçenekler (Functional Options) burada devreye girer. Fonksiyonunuz belirli bir şekilde ve yapıda ekstra argümanlar alır. Bu argümanlar daha sonra yalnızca kendileriyle ilgili olan alanları geçersiz kılar, diğerlerini değil! Aşağıdaki örneğe bakın.


Fonksiyon


package main

import (
"fmt"
)

type Car struct {
make string
model string
colour string
}

func NewCar() *Car {
return &Car{
make: "BMW",
model: "3.18",
colour: "Silver",
}
}

func main() {
car := NewCar()

fmt.Printf("%+v\n", car)
}

Elimizdeki bu ama şimdilik işe yaramaz.


&{make:BMW model:3.18 colour:Silver}

İşlevsel Seçenekler


Şimdi Car yapısını başlatma sırasında modifikasyona açık hale getirmek için Seçenekler Kalıbı (Options Pattern) uygulayalım.


package main

import (
"fmt"
)

type Car struct {
make string
model string
colour string
}

type Option func(*Car)

func Make(v string) Option {
return func(c *Car) {
c.make = v
}
}
func Model(v string) Option {
return func(c *Car) {
c.model = v
}
}
func Colour(v string) Option {
return func(c *Car) {
c.colour = v
}
}

func NewCar(opts... Option) *Car {
c := &Car{
make: "BMW",
model: "3.18",
colour: "Silver",
}

for _, opt := range opts {
opt(c)
}

return c
}

func main() {
car1 := NewCar()
fmt.Printf("%+v\n", car1)

car2 := NewCar(Make("Mercedes"), Model("SEL 500"))
fmt.Printf("%+v\n", car2)
}

Şu anda elimizde son derece özelleştirilebilir bir örnek var. Mesela rengi olduğu gibi bıraktık.


&{make:BMW model:3.18 colour:Silver}
&{make:Mercedes model:SEL 500 colour:Silver}