---
id: 548504c5a0b4857763527603f3e1059e
author: snowmerak
title: Any, Any değildir, ama Any, Any'dir
description: Go dilindeki `any` türünü ve dahili `EFace` yapısını ayrıntılı olarak inceler, `reflect` paketi ile tür iddiası (type assertion) ve tür anahtarı (type switch) kullanılarak dinamik tür işlemenin yöntemlerini açıklarım.
language: tr
date: 2025-09-30T15:12:53.689280321Z
path: /blog/posts/any-is-not-any-but-any-is-any-z6161856d
category: language
---

## Any

Go dilinde any türü, her türdeki değeri tutabilen sihirli bir arayüz olan `interface{}`'in takma adıdır. Yani herhangi bir tür, any türündeki bir değişkene atanabilir.

```go
var a any
a = 42          // int
a = "hello"     // string
a = true        // bool
a = 3.14        // float64
```

Bu şekilde any türü, çeşitli türlerdeki değerleri tutabildiği için esnek kod yazmayı mümkün kılar. Ancak any türünü kullanırken dikkat edilmesi gereken birkaç husus vardır.

### Type Assertion

any türündeki bir değişkenin gerçek değerini kullanmak için tür iddiası (type assertion) kullanılmalıdır. Tür iddiası, any türündeki bir değişkenin belirli bir tür olduğunu derleyiciye bildirir.

```go
var a any = "hello"
str, ok := a.(string)
if ok {
    fmt.Println("String value:", str)
} else {
    fmt.Println("Not a string")
}
```

Yukarıdaki örnekte `a.(string)`, `a`'nın string türünde olduğunu iddia eder. Eğer `a` string türünde değilse, `ok` false olur ve programın panic durumuna girmesi önlenir.

### Type Switch

Tür anahtarı (type switch), any türündeki bir değişkenin gerçek türüne göre farklı işlemler yapılmasını sağlar. Bu, birden fazla türün işlenmesi gerektiğinde kullanışlıdır.

```go
var a any = 42
switch v := a.(type) {
case int:
    fmt.Println("Integer:", v)
case string:
    fmt.Println("String:", v)
case bool:
    fmt.Println("Boolean:", v)
default:
    fmt.Println("Unknown type")
}
```

Yukarıdaki örnekte `a.(type)`, `a`'nın gerçek türünü denetler ve bu türe uygun durumu çalıştırır.

### Reflection

Go dilinin reflect paketini kullanarak any türündeki bir değişkenin türünü ve değerini çalışma zamanında dinamik olarak denetleyip değiştirebilirsiniz. Bu, karmaşık veri yapılarıyla çalışırken kullanışlıdır.

```go
import (
    "fmt"
    "reflect"
)

var a any = 3.14
v := reflect.ValueOf(a)
fmt.Println("Type:", v.Type())
fmt.Println("Value:", v.Float())
```

Yukarıdaki örnekte reflect paketi kullanılarak `a`'nın türü ve değeri çalışma zamanında kontrol edilebilir.

## EFace

Go dilinde arayüzler iki temel biçime ayrılır: EFace (Empty Interface) ve IFace (Interface with Methods). Bunlardan EFace, şimdiye kadar ele aldığımız any türüyle aynı kavramdır.

### Yapı

EFace yalnızca Go dilinin çalışma zamanı içinde var olan özel bir yapı olduğundan, burada bir taklit (mimic) oluşturarak çalışacağız.

```go
type runtimeTypeMimic struct {
	Size_       uintptr
	PtrBytes    uintptr // number of (prefix) bytes in the type that can contain pointers
	Hash        uint32  // hash of type; avoids computation in hash tables
	TFlag       uint8   // extra type information flags
	Align_      uint8   // alignment of variable with this type
	FieldAlign_ uint8   // alignment of struct field with this type
	Kind_       uint8   // enumeration for C
	Equal       func(unsafe.Pointer, unsafe.Pointer) bool
	GCData      *byte
	Str         int32 // string form
	PtrToThis   int32 // type for pointer to this type, may be zero
}

type eFaceMimic struct {
	Type *runtimeTypeMimic
	Data unsafe.Pointer
}
```

EFace iki alana sahiptir:

- `Type`: Değerin gerçek türüne ilişkin meta verileri tutan bir işaretçidir.
- `Data`: Gerçek değeri tutan bir işaretçidir.

Ayrıca EFace, tür bilgisini dahili olarak `runtimeType` yapısı aracılığıyla yönetir. Bu yapı, türün boyutu, hizalaması, hash değeri gibi çeşitli meta verileri içerir.

Bu yapı içinde dikkat etmemiz gereken kısımlar `Kind_`, `Hash` ve `Equal` alanlarıdır. `Kind_` türün cinsini gösterirken, `Hash` ve `Equal` hash tablolarında türleri karşılaştırmak ve hash değerini hesaplamak için kullanılır.

### Sarmalama

Şimdi bu EFace'i sararak kara büyüyü daha rahat kullanabileceğimiz bir yapı oluşturalım.

```go
type TypeInfo struct {
	Hash  uint32
	TFlag uint8
	Kind  uint8
	Equal func(unsafe.Pointer, unsafe.Pointer) bool
	This  unsafe.Pointer
}

func GetTypeInfo(v any) TypeInfo {
	eface := *(*eFaceMimic)(unsafe.Pointer(&v))
	return TypeInfo{
		Hash:  eface.Type.Hash,
		TFlag: eface.Type.TFlag,
		Kind:  eface.Type.Kind_,
		Equal: eface.Type.Equal,
		This:  eface.Data,
	}
}
```

Yukarıdaki fonksiyon, any türündeki bir değişkeni alır, içindeki EFace yapısını çıkarır, bu yapıdan tür bilgisini alıp `TypeInfo` yapısı olarak döndürür. Artık bu `TypeInfo` ile türün hash değerine, cinsine, karşılaştırma fonksiyonuna vb. kolayca erişebilirsiniz.

### Kullanım

Kullanımı gerçekten kolaydır. Sadece `GetTypeInfo` fonksiyonuna any türündeki bir değişkeni vermeniz yeterlidir.

```go
func main() {
	i := 42
	eface := GetTypeInfo(i)
	fmt.Printf("%+v\n", eface)

	f := 3.14
	eface2 := GetTypeInfo(f)
	fmt.Printf("%+v\n", eface2)

	// Compare the two values using the Equal function from the type info
	log.Println(eface.Equal(eface.This, eface.This))
	log.Println(eface2.Equal(eface2.This, eface2.This))
	log.Println(eface2.Equal(eface.This, eface2.This))
	log.Println(eface.Equal(eface2.This, eface.This))
}
```

Yukarıdaki örnekte tam sayı ve ondalıklı sayı değerleri `GetTypeInfo` fonksiyonuna verilerek her birinin tür bilgisi yazdırılır ve `Equal` fonksiyonu kullanılarak değerler karşılaştırılır. Bu sayede tür bilgisine daha hızlı erişilebilir ve türler karşılaştırılabilir.

Ayrıca bu yöntem yapılar, işaretçiler, arayüzler gibi tiplerde de aynı şekilde kullanılabilir ve sıkça karşılaşılan bir sorun olan tür bilgisi olan nil (typed nil) problemini de çözebilir. `Hash` tür atanmışsa dolu olacaktır, ancak `This` nil ise 0 olacaktır.

## Sonuç

EFace, günümüzde Go dilinde any türünün ele alınmasında önemli bir rol oynamaktadır. Bu sayede çeşitli türlerdeki değerler esnek ve hızlı biçimde işlenebilir, tür bilgisi ayrıntılı olarak elde edilip kullanılabilir. Ancak bu özellik çalışma zamanı içinde gizli bir işlevselliktir ve dil spesifikasyonundaki değişikliklerden etkilenebileceği için dikkatli olunmalıdır.
