이동 함수 인자는 값에 의해 전달된다.
우선, 예제의 관련성이없는 부분을 버리십시오. 그러면 값으로 인수를 전달하는 것만 알 수 있습니다. 예를 들어,
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)
}
출력 : 함수 main
에서
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
는 i
메모리 위치를 초기 값 (i
) 42
와 (&i
) 0xf800000040
에서 int
변수이다. 함수에서 main
, p
은 int
42
값 (= i
*p
)를 가리키는 값 (= &i
p
) 0xf800000040
함께 메모리 위치 (&p
) 0xf8000000f0
에서 int
변수에 대한 포인터이다. 함수 main
에서
, byval(p)
는 메모리 위치 (&q
) 0xf8000000d8
의 함수 byval
파라미터 q
에 값 (= &i
p
) 메모리 위치 (&p
) 0xf8000000f0
의 인수 0xf800000040
를 할당하는 함수를 호출한다. 즉, byval
매개 변수 q
에 대해 메모리가 할당되고 main
byval
인수 p
의 값이 할당됩니다. p
과 q
의 값은 처음에는 같지만 변수 p
과 q
이 다릅니다.포인터 p
(*int
)의 복사 포인터 q
(*int
), 정수 *q
(i
)을 이용하여 함수 byval
에서
는 새로운 4143
int 값으로 설정된다. 결국 돌아 오기 전에. 포인터 q
은 nil
(제로 값)으로 설정되며 q
이 사본이기 때문에 p
에는 영향을 미치지 않습니다. 함수에서 main
, p
새로운 int
4143
값 (= i
*p
)를 가리키는 값 (= &i
p
) 0xf800000040
함께 메모리 위치 (&p
) 0xf8000000f0
에서 int
변수에 대한 포인터이다. 함수에서 main
는 i
메모리 위치의 최종 값 (i
)와 4143
(&i
) 0xf800000040
에서 int
변수이다. 하여 예에서
함수 호출 gotest
인수로서 사용되는 함수는 변수 main
s
함수 gotest
s
파라미터와 동일하지 않다. 이름은 같지만 스코프와 메모리 위치가 다른 변수입니다. 함수 매개 변수 s
은 함수 호출 인수 s
을 숨 깁니다. 그래서 필자는 예제에서 매개 변수 변수 인 p
과 q
을 각각 차이를 강조하기 위해 명명했습니다.
하여 예에서
(&s
) 0x4930d4
함수 호출 gotest(s, done)
인수로서 사용되는 함수 main
에서 변수 s
의 메모리 위치의 주소이며, 0x4974d8
는 함수 메모리 위치의 주소 gotest
매개 변수 s
. 함수 gotest
의 끝에 s = nil
매개 변수를 설정하면 main
의 변수 s
에 영향을 미치지 않습니다. s
은 main
이고 s
은 gotest
이며 서로 다른 메모리 위치입니다. 유형별로 &s
은 **Something
, s
은 *Something
, *s
은 Something
입니다. &s
은 Something
유형의 익명 변수 (메모리 위치 주소)에 대한 포인터 인 (메모리 위치 주소) s
에 대한 포인터입니다. 값의 측면에서, main.&s != gotest.&s
, main.s == gotest.s
, main.*s == gotest.*s
및 main.s.number == gotest.s.number
.
당신은 mkb의 현자의 조언을 가지고 println(&s)
을 사용하지 말아야합니다. 예를 들어, fmt
패키지를 사용
fmt.Printf("%v %p %v\n", &s, s, *s)
가 동일한 메모리 위치를 가리킬 때 포인터가 같은 값을 가지고, 포인터는 다른 메모리 위치를 가리킬 때 다른 값을 갖습니다.
내 예제에서 gotest는 'Something'에 대한 포인터를 취해서 같은 객체를 가리키는 것으로 가정하고 명확히 말하면 이동 루틴 내부의 값을 변경하면 객체의 주 값이 변경됩니다 기능. 인쇄 된 포인터 값이 다릅니다. –
@JamesDean 예에서는 포인터 값 유형을 인쇄합니다. ** 뭔가 포인터 값과 같지 않습니다. 유형 * 뭔가. 포인터를 값으로 전달하기 위해 예제를 수정했습니다. – peterSO
@James Dean 포인터의 주소 (즉,'s' 포인터에 대한 포인터)를 출력했습니다. - 포인터는 값으로 전달되고,'s'의 주소는's'와 같지 않습니다. 만약 당신의 gotest 함수가'println (s)'을 쓰면 포인터 값을 출력 할 것입니다. – nos