İşaretçiler birkaç nedenden dolayı faydalıdır. İşaretçiler bellek düzeni üzerinde kontrole izin verir (CPU önbelleğinin verimliliğini etkiler). Go'da, tüm üyelerin bitişik bellekte olduğu bir yapı tanımlayabiliriz:
type Point struct {
x, y int
}
type LineSegment struct {
source, destination Point
}
Bu durumda Point
yapılar yapının içine gömülüdür LineSegment
. Ancak verileri her zaman doğrudan gömemezsiniz. İkili ağaçlar veya bağlantılı liste gibi yapıları desteklemek istiyorsanız, bir tür işaretçi desteklemeniz gerekir.
type TreeNode {
value int
left *TreeNode
right *TreeNode
}
Java, Python vb. Bu soruna sahip değildir çünkü kompozit türleri yerleştirmenize izin vermez, bu nedenle gömme ve işaretleme arasında sözdizimsel olarak ayrım yapmaya gerek yoktur.
Go işaretçileriyle çözülen Swift / C # yapılarıyla ilgili sorunlar
Aynısını başarmanın olası bir alternatifi , C # ve Swift'in yaptığı gibi struct
ve arasında ayrım class
yapmaktır. Ancak bunun sınırlamaları var. Yapının inout
kopyalanmasını önlemek için genellikle bir işlevin parametre olarak bir yapı aldığını belirtebilirsiniz , ancak yapılara referansları (işaretçiler) depolamanıza izin vermez. Bu, bir yapıyı, örneğin bir havuz ayırıcısı oluşturmak için yararlı bulduğunuzda asla referans türü olarak ele alamayacağınız anlamına gelir (aşağıya bakın).
Özel Bellek Ayırıcı
İşaretçileri kullanarak kendi havuz ayırıcınızı da oluşturabilirsiniz (bu, yalnızca prensibi göstermek için birçok denetim kaldırılarak çok basitleştirilmiştir):
type TreeNode {
value int
left *TreeNode
right *TreeNode
nextFreeNode *TreeNode;
}
var pool [1024]TreeNode
var firstFreeNode *TreeNode = &pool[0]
func poolAlloc() *TreeNode {
node := firstFreeNode
firstFreeNode = firstFreeNode.nextFreeNode
return node
}
func freeNode(node *TreeNode) {
node.nextFreeNode = firstFreeNode
firstFreeNode = node
}
İki değeri değiştirin
İşaretçiler ayrıca uygulamanıza izin verir swap
. Bu, iki değişkenin değerlerini değiştirmektir:
func swap(a *int, b *int) {
temp := *a
*a = *b
*b = temp
}
Sonuç
Java, Google gibi yerlerde sistem programlaması için C ++ 'ın yerini hiçbir zaman tam olarak değiştiremedi, çünkü kısmen, bellek düzenini ve kullanımını kontrol etme becerisinin olmaması nedeniyle performans aynı ölçüde ayarlanamıyor (önbellek kayıpları performansı önemli ölçüde etkiler). Go, birçok alanda C ++ 'ın yerini almayı hedefledi ve bu nedenle işaretçileri desteklemesi gerekiyor.