Go işlevi bağımsız değişkenleri değer ile iletilir.
Öncelikle, bir argümanı yalnızca değere göre ilettiğinizi kolayca görebilmemiz için örneğinizin alakasız kısımlarını bir kenara atalım. Örneğin,
package main
import "fmt"
func byval(q *int) {
fmt.Printf("3. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n", q, &q, q, *q)
*q = 4143
fmt.Printf("4. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n", q, &q, q, *q)
q = nil
}
func main() {
i := int(42)
fmt.Printf("1. main -- i %T: &i=%p i=%v\n", i, &i, i)
p := &i
fmt.Printf("2. main -- p %T: &p=%p p=&i=%p *p=i=%v\n", p, &p, p, *p)
byval(p)
fmt.Printf("5. main -- p %T: &p=%p p=&i=%p *p=i=%v\n", p, &p, p, *p)
fmt.Printf("6. main -- i %T: &i=%p i=%v\n", i, &i, i)
}
Çıktı:
1. main -- i int: &i=0xf840000040 i=42
2. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=42
3. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=42
4. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=4143
5. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=4143
6. main -- i int: &i=0xf840000040 i=4143
Fonksiyonunda main, ibir bir intbellek konumunda bir değişken ( &i) 0xf800000040bir başlangıç değeri ile ( i) 42.
Fonksiyonda main, bir değere ( = ) işaret eden bir değere ( = ) sahip bellek konumundaki ( ) pbir intdeğişkene göstericidir .&p0xf8000000f0p&i0xf800000040int*pi42
Fonksiyonda main, byval(p)değeri (atar bir işlev çağrısı p= &i) 0xf800000040bellek konumu (en argüman &p) 0xf8000000f0fonksiyonu byvalparametre qbellek konumunda ( &q) 0xf8000000d8. Başka bir deyişle, byvalparametre için bellek ayrılır qve main byvalbağımsız değişkenin değeri pona atanır; değerleri pve qilk olarak aynıdır, ancak değişkenler pve qfarklıdır.
İşlevde byval, pointer q( *int) 'ın bir kopyası olan pointer p( *int) kullanılarak integer *q( i) yeni bir int değerine ayarlanır 4143. Dönmeden önce sonunda. işaretçi (sıfır değeri) qolarak ayarlanmıştır nil, bu bir kopya polduğundan üzerinde hiçbir etkisi yoktur q.
Fonksiyonunda main, pbir bir işaretçidir intbellek konumu (değişkenin &p) 0xf8000000f0değeri ile ( p= &i) 0xf800000040, yeni olduğu noktaları intdeğeri ( *p= i) 4143.
İşlevsel olarak main, bellek konumunda ( ) son değeri ( ) iolan bir intdeğişkendir .&i0xf800000040i4143
Örneğinizde, işlev çağrısına bağımsız maindeğişken olarak skullanılan işlev değişkeni gotest, işlev gotestparametresiyle aynı değildir s. Aynı ada sahiptirler, ancak farklı kapsamlara ve bellek konumlarına sahip farklı değişkenlerdir. İşlev parametresi s, işlev çağrısı bağımsız değişkenini gizler s. Bu yüzden örneğimde argüman ve parametre değişkenlerini adlandırdım pve qsırasıyla farkı vurgulamak için.
Örnekte, ( &s) 0x4930d4değişken için hafıza konumunun adresidir sişlevinde mainişlev çağrısı argüman olarak kullanılır gotest(s, done)ve 0x4974d8fonksiyon için hafıza konumunun adresidir gotestparametresi s. Parametreyi s = nilfonksiyonun sonunda ayarlarsanız gotest, değişken sin üzerinde etkisi olmaz main; siçinde mainve siçinde gotestfarklı bellek konumlarıdır. Türleri açısından, &solduğu **Something, solduğunu *Something, ve *sbir Something. &s(bellek konumu adresi) siçin bir göstericidir, bu bir işaretçi (bellek konumu adresi) bir tür anonim değişkenSomething. Değerler açısından, main.&s != gotest.&s, main.s == gotest.s, main.*s == gotest.*s, ve main.s.number == gotest.s.number.
MKB'nin bilgece tavsiyesini dinlemeli ve kullanmayı bırakmalısınız println(&s). fmtPaketi kullanın, örneğin,
fmt.Printf("%v %p %v\n", &s, s, *s)
İşaretçiler aynı bellek konumuna işaret ettiklerinde aynı değere sahiptir; işaretçiler, farklı bellek konumlarına işaret ettiklerinde farklı değerlere sahiptir.