1 Fonksiyon Temelleri
Programlamada, bir fonksiyon belirli bir görevi yerine getiren ve girdi parametreleri ve dönüş değerleri olabilen bir kod parçasıdır. Go dilinde fonksiyonlar, kodu düzenlemek ve tekrar kullanmak için yaygın olarak kullanılır. Fonksiyonları etkili bir şekilde kullanmak, kodu daha öz, okunaklı ve bakımı kolay hale getirebilir.
Fonksiyonlar, Go dilinin temel bir bileşenidir ve fonksiyonların nasıl bildirildiğini ve tanımlandığını anlamak, verimli ve okunabilir kod yazmak için çok önemlidir.
2 Fonksiyon Tanımlama
2.1 Fonksiyon Bildirimi
Go dilinde genel fonksiyon bildiriminin formu şöyledir:
func fonksiyonAdı(parametreler) dönüşTipi {
// Fonksiyon gövdesi
}
Bu bileşenleri inceleyelim:
-
func
anahtarı bir fonksiyonu bildirmek için kullanılır. -
fonksiyonAdı
, Go dilinin isimlendirme kurallarını izleyen fonksiyonun adıdır. Büyük harfle başlayan bir fonksiyon dış pakette görünür, küçük harfle başlayan bir fonksiyon ise görünür değildir ve yalnızca aynı paket içinde kullanılabilir. -
parametreler
, virgülle ayrılmış fonksiyonun aldığı parametrelerin listesidir. Her parametrenin türü belirtilmelidir ve birden fazla parametrenin aynı tipe sahip olması durumunda tür yalnızca bir kez belirtilmelidir. -
dönüşTipi
, fonksiyonun dönüş değerinin türüdür. Fonksiyon bir değer döndürmüyorsa, bu kısım atlanabilir. Fonksiyon birden fazla değer döndürüyorsa, bunlar parantez içinde olmalıdır.
Örneğin, iki tamsayının toplamını hesaplayan basit bir fonksiyonu şu şekilde bildirebiliriz:
func Topla(a int, b int) int {
return a + b
}
Bu örnekte, fonksiyon adı Topla
, a
ve b
tipinde iki parametre alır ve dönüş türü int
olan bu parametrelerin toplamını döndürür.
2.2 Parametre Listesi
Parametre listesi, fonksiyonun hangi parametreleri kabul ettiğini ve her bir parametrenin türünü tanımlar. Parametreler, bir fonksiyona veri iletmek için kullanılan özel bir değişken türüdür.
func SelamVer(isim string, yaş int) {
fmt.Printf("Merhaba, %s! Sen %d yaşındasın.\n", isim, yaş)
}
Bu SelamVer
fonksiyonunda, isim
ve yaş
parametreleridir. isim
'in türü string
, yaş
'ın türü ise int
'dir. Bu fonksiyonu çağırırken, bu parametreler için gerçek değerler sağlanmalıdır.
2.3 Dönüş Tipleri
Fonksiyonlar hesaplanmış sonuçları döndürebilir ve dönüş türü, fonksiyonun dönüş değerinin veri tipini tanımlar. Bir fonksiyonun dönüş değeri olmayabilir veya bir veya daha fazla dönüş değeri olabilir.
Bir fonksiyonun birden fazla dönüş değeri olduğunda, bunların bildirim sırasında parantez içine alınması gerekir:
func Böl(bölünen, bölen float64) (float64, error) {
if bölen == 0 {
return 0, errors.New("sıfıra bölemezsin")
}
return bölünen / bölen, nil
}
Buradaki Böl
fonksiyonu iki değer döndürür: bölüm ve bir hata mesajı. Eğer bölen sıfırsa bir hata döndürülür.
2.4 Değişken Sayıda Parametreler
Golang'da, bir fonksiyonun tanımlanırken çağrıcının kaç parametre ile çağrılacağını tam olarak bilmediğimiz durumlarda, değişken sayıda parametreler kullanabiliriz. Değişken sayıda parametreler üç nokta ...
ile belirtilir ve bu, fonksiyonun herhangi bir sayıda parametreyi kabul edebileceği anlamına gelir. Bu, belirsiz miktarda veri ile ilgilenirken veya belirli türdeki işlevleri uygularken çok kullanışlıdır.
Uygulama Senaryoları
Değişken parametreler aşağıdaki senaryolarda yaygın olarak kullanılır:
-
String birleştirme:
fmt.Sprintf
vestrings.Join
gibi işlevlerde olduğu gibi. - Dizi/slice işleme: değişken uzunlukta diziler veya slice'larla uğraşırken, toplamı hesaplama veya birden fazla slice'ı birleştirme gibi durumlarda kullanılır.
-
Günlük kaydı ve hata işleme: Birden fazla hatayla uğraşırken veya birden fazla günlük bilgisini kaydederken,
log.Printf
veya özel hata özeti işlevleri gibi durumlarda kullanılır. - Yardımcı fonksiyonlar: Kullanıcılara işlevleri çağırma için daha esnek yollar sunmak amacıyla API'lerde veya kütüphanelerde kullanılır.
Değişken Parametreler Kullanımı
İşte değişken parametrelerin basit bir örneği:
// Değişken sayıda tamsayı parametresi alan ve bunların toplamını döndüren bir fonksiyon tanımla
func Topla(sayılar ...int) int {
toplam := 0
for _, sayı := range sayılar {
toplam += sayı
}
return toplam
}
func main() {
// Herhangi bir sayıda parametre geçirebilirsin
fmt.Println(Topla(1, 2)) // Çıktı: 3
fmt.Println(Topla(1, 2, 3, 4)) // Çıktı: 10
// Bir dilim geçebilir ve dilimin sonrasına üç nokta işareti koyabilirsin
sayılar := []int{1, 2, 3, 4, 5}
fmt.Println(Topla(sayılar...)) // Çıktı: 15
}
Topla
fonksiyonunda, sayılar
, Topla
fonksiyonuna verilen tüm parametreleri içeren bir tamsayı dilimidir. Bu dilim üzerinde döngü kullanarak toplamı hesaplayabiliriz.
Fonksiyon içindeki değişken parametreler aslında bir dilimidir, bu nedenle tüm dilimle ilgili işlemler kullanılabilir. Bir dilimi değişken parametre olarak bir fonksiyona geçirmeniz gerektiğinde, dilimin sonrasına yani ...
işaretini ekleyerek yapabilirsiniz.
Değişken parametrelerin kullanılması fonksiyon çağrılarını daha esnek ve özlü hale getirebilir, ancak değişken parametrelerin kullanılması dilim oluşturma ve bellek tahsisi gerektirdiğinden hafif bir performans etkisi olacaktır. Bu nedenle, katı performans gereksinimleri olduğunda dikkatli olunmalıdır.
İpucu: Dilimlerle ilgili detaylı açıklamalar ilerleyen bölümlerde sunulacaktır. Diğer programlama dillerinde deneyiminiz varsa, onları geçici olarak diziler şeklinde düşünebilirsiniz.
3 Fonksiyonları Çağırmak
3.1 Temel Fonksiyon Çağrıları
Bir fonksiyonu çağırmak, fonksiyonun kodunu yürütmek anlamına gelir. Go'da bir tanımlı fonksiyonu çağırmak oldukça basittir, sadece fonksiyon adını kullanın ve uygun parametreleri geçin. Örneğin:
sonuç := ekle(3, 4)
fmt.Println(sonuç) // Çıktı: 7
Bu örnekte, ekle
fonksiyonu çağrılır ve iki tamsayı parametre olarak geçilir, ardından dönen sonuç sonuç
değişkenine atanır.
3.2 Parametre Geçme
Bir fonksiyona parametre geçirirken, Go, varsayılan olarak değer ile geçme kullanır, yani parametre değerinin bir kopyasını geçer ve orijinal veri değişmez. Ancak fonksiyonun dış değişkenleri değiştirmesini istiyorsanız veya performans nedenleriyle büyük yapılar geçirmek istiyorsanız, işaretçiler kullanarak veya büyük yapıları geçirerek referans ile geçme yöntemini kullanabilirsiniz.
Değer ile geçme ve referans ile geçme örnekleri şunlardır:
// Değer ile geçme örneği
func ikiyleÇarp(sayı int) {
sayı *= 2
}
// Referans ile geçme örneği
func ikiyleÇarpPtr(sayı *int) {
*sayı *= 2
}
func main() {
değer := 3
ikiyleÇarp(değer)
fmt.Println(değer) // 3, değer değişmeden kalır
ikiyleÇarpPtr(&değer)
fmt.Println(değer) // 6, değer iki katına çıkar
}
Yukarıdaki örnekte, ikiyleÇarp
fonksiyonu geçilen sayı
yı iki katına çıkarmaya çalışır, ancak yalnızca bir kopyasını iki katına çıkarır, orijinal değer
değişkeni değişmez. Ancak ikiyleÇarpPtr
fonksiyonu, bir tamsayı değişkeninin işaretçisini parametre olarak alarak orijinal değişkenin değerini değiştirir.