ProgramlamaGo geliştirici

Go'da isteğe bağlı parametreler ve varsayılan değerlerle çalışma özelliklerini açıklayın ve minimum katılık ile işlev arayüzlerini nasıl esnek bir şekilde uygulayabilirsiniz

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Go, fonksiyon argümanları için isteğe bağlı parametreler ve varsayılan değerleri yerel olarak desteklemiyor — her fonksiyon yalnızca imzasında belirtilen argüman setini kabul ediyor. Bu tasarım kararı, modelin genel sadeliği ve kodun öngörülebilirliği ile ilgilidir.

Tarih

Diğer dillerde, örneğin Python veya C++, isteğe bağlı/varsayılan parametreler, bir fonksiyonun davranışını esnek bir şekilde tanımlamaya olanak tanır. Go, okuma ve kesinlik için bunu feda etti.

Sorun

API'yi esnek hale getirmek istediğinizde, varsayılan değerleri basitçe belirlemek mümkün değildir — tüm parametreleri açıkça geçmeniz veya dolaylı desenler kullanmanız gerekir. Bu, birçok seçenek eklemek için desteği zorlaştırır ve aşırı yüklenmiş fonksiyon sayısının artmasına yol açabilir.

Çözüm

Go'da bu tür bir esneklik için iki yaklaşım kullanılır:

  1. Parametre-yapısı — bir dizi seçenek alanına sahip bir yapı oluşturulur ve bu yapı fonksiyona geçirilebilir. Yapı içinde varsayılan değerler açıkça belirlenebilir.
  2. Değişken fonksiyonlar (functional options pattern) — nesnenin yapılandırmasını değiştiren ayar fonksiyonlarını geçirme deseni.

Yapı aracılığıyla yaklaşım örneği:

type QueryOptions struct { Limit int Offset int } func QueryDB(opts QueryOptions) { if opts.Limit == 0 { opts.Limit = 10 // varsayılan } // ... } QueryDB(QueryOptions{Limit: 100})

Ya da işlevsel seçenekler aracılığıyla:

type Config struct { Timeout int } type Option func(*Config) func WithTimeout(t int) Option { return func(cfg *Config) { cfg.Timeout = t } } func Do(opts ...Option) { cfg := Config{Timeout: 5} // varsayılan for _, o := range opts { o(&cfg) } // ... } Do(WithTimeout(10)) // seçenek ile çağrı Do() // varsayılan ile çağrı

Anahtar özellikler:

  • Dil düzeyinde isteğe bağlı/varsayılan parametreler yoktur
  • Esneklik ya yapılar ya da fonksiyonel desenle sağlanır
  • Her şey açık, sihir yok — her zaman neyin ve nasıl geçtiği görünür

Yanlış anlamaya açık sorular.

Fonksiyonun ilanında varsayılan bir değer belirlemek mümkün mü, örneğin func F(a int = 10)?

Hayır, Go'da böyle bir kayıt açılamaz — yalnızca gerekli parametrelerin kesin bir listesi.

...interface{} türünde bir dilimle fonksiyon ilan edilirse ve 0 argüman ile geçilirse ne olur?

Dilim 0 uzunluğuna (nil) sahip olacaktır, fonksiyon boş bir dilim alacaktır.

Kod örneği:

func PrintAll(args ...interface{}) { fmt.Println(len(args)) // parametre geçmezse 0 } PrintAll() // tamam

Go'da parametre sayısına veya türüne göre fonksiyonları aşırı yükleyebilir miyiz?

Hayır, Go'da fonksiyon aşırı yüklemesi desteklenmez — farklı imzalara sahip aynı isimdeki fonksiyonlar kabul edilmez.

Tipik hatalar ve anti-deseni

  • Değişken arayüzler ile aşırı yüklemeye çalışmak (...interface{}), elle karmaşık tür kontrolleri yapmak
  • API'yi onlarca parametreye kadar aşırı derecede genişletmek — bu, bakımı zorlaştırır
  • Fonksiyonlar içinde yapılandırma imkanı olmadan değerleri sabitlemek

Gerçek hayattan bir örnek

Olumsuz durum

API fonksiyonu onlarlaca parametreye sahiptir, bunların çoğu aynı türdendir, yanlışlıkla sırayı karıştırır:

Artıları:

  • Her şey açıkça belirtilmiştir

Eksileri:

  • Belirsiz argümanlar yüzünden hatalar
  • Varsayılan değerlerin ne olduğunu anlamak zor

Olumlu durum

Seçenek yapısı veya fonksiyonel seçenekler kullanılır, parametrelerin açık isimleri vardır:

Artıları:

  • Esnek ve genişletilebilir imza
  • Belirsizlik olmaksızın varsayılanların desteklenmesi

Eksileri:

  • Ek bir "sarmalayıcı" (yapılar, seçenek fonksiyonları) desteklemek gerekir