Go’da İnterface Semantiği

Murat Demir
2 min readDec 26, 2023

--

İnterface Semantiğine derinlemesine dalmadan önce bazı bilgilerin üzerinden geçmek iyi olacaktır.

Değer Semantiği, değişkene atanan değeri temsil eder. Bu değer başka bir değişkene aktarıldığında orijinal değişkenin değeri kopyalanır ve bu iki değişken artık birbirinden bağımsızdır. Bir değişkenin değeri değiştirildiğinde diğer değişken bu durumdan etkilenmez.

https://go.dev/play/p/Mmy6fMWrFWM

İşaretçi Semantiği, değişkene atanan değerin bellekteki adresini temsil eder. Bu adres aracılığıyla, değişkenin değerine dolaylı yoldan erişilebilir. Özetle, işaretçi aracılığıyla değişkenin üzerinde yapılan değişiklikler, işaretçinin gösterdiği bellek adresindeki değeri etkiler. İşaretçinin gösterdiği bellek adresindeki değer değiştirildiğinde, bu değişiklik diğer tüm referanslar ve orijinal değişken üzerinde de yansır.

https://go.dev/play/p/YUg2RVZo3f8

Not: Değer semantiği değerleri stack kısmında tutar bu da GC(Garbage Collector) üzerindeki baskıyı azaltır. İşaretçi semantiği değerleri heap kısmında tutar bu da GC üzerindeki baskıyı arttırır.

Arayüz bir değerin kendi kopyasını ya da değerin adresini saklayabilir. Bu cümleyi daha iyi anlamak için minik kir kod parçacığı ile netleştirelim.

package main

import "fmt"

type Printer interface {
Print()
}

type Foo struct {
Bar string
}

func (f Foo) Print() {
fmt.Println("Value ", f.Bar)
}

func main() {

foo := Foo{
Bar: "Go",
}

fooList := []Printer{
foo,
&foo,
}

foo.Bar = "lang"

for _, f := range fooList {
f.Print()
}

}

Value Go
Value lang

Arayüzler Değersizdir (Interfaces are valueless)

Burada da derinlemesine dalmadan önce aşağıdaki tabloyu hatırlamak faydalı olacaktır.

Tabloda göreceğiniz üzere value receiver hem değer hem de pointer value kabul ediyor. Pointer receiver sadece pointer değerini kabul ediyor. Peki pointer receiver neden sadece pointer kabul ediyor. Bunun iki nedeni var:

  1. Her değerin adreslenebilir olduğunu garanti edemeyiz.
  2. Pointer ile işaret edilen herhangi bir değerin kopyasını oluşturmak safe zone’dan çıkmak anlamına gelir.

Tabloyu ve nedenleri inceledikten sonra “valueless”a geçebiliriz.

type notifier interface {
notify()
}

type duration int

func (d duration) notify() {
fmt.Println("Sending Notification in", d)
}

func main() {
// n değişkeni burada notifier tipinde oluşturuldu ve sıfır değerinde yani nil interface
var n notifier
// n değişkeni buraya kadar "valueless" idi. Bu satıra kadar herhangi bir somut değere sahip değildir.
n = duration(42)
n.notify()
}

Özet

Go dilinde arayüzler (interfaces) value semantiği üzerine kurulu olduğu için, arayüzler değerlerle çalışır. Arayüzler, değerlerin kopyalarını ya da bellek adreslerini saklayabilirler, ancak valueless (değersiz) olarak adlandırılır, çünkü value receiver ve pointer receiver ayrımı, arayüzlerin içerdiği değerlere bağlı olarak değil, sadece bu değerlerle nasıl etkileşimde bulunulduğuna bağlı olarak önem kazanır.

Ref:

Ultimate Go Notebook Git
Go In Action
Git

--

--