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
, i
bir bir int
bellek konumunda bir değişken ( &i
) 0xf800000040
bir başlangıç değeri ile ( i
) 42
.
Fonksiyonda main
, bir değere ( = ) işaret eden bir değere ( = ) sahip bellek konumundaki ( ) p
bir int
değişkene göstericidir .&p
0xf8000000f0
p
&i
0xf800000040
int
*p
i
42
Fonksiyonda main
, byval(p)
değeri (atar bir işlev çağrısı p
= &i
) 0xf800000040
bellek konumu (en argüman &p
) 0xf8000000f0
fonksiyonu byval
parametre q
bellek konumunda ( &q
) 0xf8000000d8
. Başka bir deyişle, byval
parametre için bellek ayrılır q
ve main
byval
bağımsız değişkenin değeri p
ona atanır; değerleri p
ve q
ilk olarak aynıdır, ancak değişkenler p
ve q
farklı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) q
olarak ayarlanmıştır nil
, bu bir kopya p
olduğundan üzerinde hiçbir etkisi yoktur q
.
Fonksiyonunda main
, p
bir bir işaretçidir int
bellek konumu (değişkenin &p
) 0xf8000000f0
değeri ile ( p
= &i
) 0xf800000040
, yeni olduğu noktaları int
değeri ( *p
= i
) 4143
.
İşlevsel olarak main
, bellek konumunda ( ) son değeri ( ) i
olan bir int
değişkendir .&i
0xf800000040
i
4143
Örneğinizde, işlev çağrısına bağımsız main
değişken olarak s
kullanılan işlev değişkeni gotest
, işlev gotest
parametresiyle 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 p
ve q
sırasıyla farkı vurgulamak için.
Örnekte, ( &s
) 0x4930d4
değişken için hafıza konumunun adresidir s
işlevinde main
işlev çağrısı argüman olarak kullanılır gotest(s, done)
ve 0x4974d8
fonksiyon için hafıza konumunun adresidir gotest
parametresi s
. Parametreyi s = nil
fonksiyonun sonunda ayarlarsanız gotest
, değişken s
in üzerinde etkisi olmaz main
; s
içinde main
ve s
içinde gotest
farklı bellek konumlarıdır. Türleri açısından, &s
olduğu **Something
, s
olduğunu *Something
, ve *s
bir Something
. &s
(bellek konumu adresi) s
iç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)
. fmt
Paketi 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.