Go를 사용하면 매개변수가 포인터(참조라고도 함)와 값을 통해 전달될 수 있습니다. 이 기사에서는 선택에 영향을 미칠 수 있는 다양한 상황에 특히 주의하면서 두 가지 접근 방식을 비교할 것입니다.
포인터 전달 및 값 전달
엄밀히 말하면 Go 메서드나 함수에는 전달 방법이 하나만 있는데, 그것이 바로 값 전달입니다. 변수가 인수로 전달될 때마다 변수의 새 복사본이 생성되어 호출되는 함수나 메서드에 전달됩니다. 복사본은 다른 메모리 주소에 할당됩니다.
포인터로 변수를 전달하는 경우 동일한 메모리 주소를 가리키는 새 복사본이 생성됩니다. 차이점을 느끼기 위해 작동 방식을 살펴보겠습니다.
값 전달
package main import "fmt" type Person struct { firstName string lastName string } func changeName(p Person) { p.firstName = "Bob" } func main() { person := Person { firstName: "Alice", lastName: "Dow", } changeName(person) fmt.Println(person) }
코드를 실행하면 다음과 같은 출력이 제공됩니다.
{Alice Dow}
changeName 함수가 firstName을 "Bob"으로 변경하더라도 변경 사항은 기본 함수의 person 변수에 영향을 주지 않습니다. 이는changeName 함수가 person 자체가 아닌 person 변수의 복사본을 수정하기 때문에 발생합니다.
포인터 전달
package main import "fmt" type Person struct { firstName string lastName string } func changeName(p *Person) { p.firstName = "Bob" } func main() { person := Person { firstName: "Alice", lastName: "Dow", } changeName(&person) fmt.Println(person) }
코드를 실행하면 다음과 같은 출력이 표시됩니다.
{Bob Dow}
이 경우 main 함수의 person 변수가changeName 함수에서 수정됩니다. 이는 &person과 p가 동일한 메모리 주소에 저장된 동일한 구조에 대한 두 개의 서로 다른 포인터이기 때문에 발생합니다.
변수는 수정할 수 없습니다
값으로 전달할 수밖에 없습니다. 따라서 이 변수는 다운스트림으로 수정될 수 없습니다. 반대로, 변수가 수정될 것으로 예상되면 포인터를 통해 전달되어야 합니다.
변수가 큰 구조입니다
변수가 큰 구조이고 성능이 문제인 경우 변수를 포인터를 통해 전달하는 것이 가장 좋습니다. 이렇게 하면 전체 구조가 메모리에 복사되는 것을 방지할 수 있습니다.
변수는 맵 또는 슬라이스입니다
Go의 맵과 슬라이스는 참조 유형이며 값으로 전달되어야 합니다.
값으로 전달하는 것이 일반적으로 저렴합니다.
Go가 C와 약간 비슷해 보이지만 컴파일러는 다르게 작동합니다. C의 비유가 Go에서 항상 작동하는 것은 아닙니다. Go에서 값으로 전달하는 것이 포인터로 전달하는 것보다 비용이 덜 들 수 있습니다. 이는 Go가 이스케이프 분석을 사용하여 변수를 함수의 스택 프레임에 안전하게 할당할 수 있는지 확인하기 때문에 발생하며, 이는 힙에 변수를 할당하는 것보다 훨씬 저렴할 수 있습니다. 값 전달은 Go에서 탈출 분석을 단순화하고 변수에 대한 더 나은 할당 기회를 제공합니다.
요약
포인터 전달과 값 전달의 차이점
1. 포인터 전달은 주소의 데이터 대신 주소를 전달하며 일반적으로 값 전달보다 효율적입니다. , 값이 아닌 포인터로 전달될 수 있습니다.
2. 포인터가 전달되면 호출 함수에서 포인터가 가리키는 공간 데이터의 수정이 호출자에게 영향을 미칩니다. 동일한 영역을 가리키기 때문에 포인터 전송은 호출자의 데이터에 영향을 미치지 않습니다.
관련 추천: golang 튜토리얼
위 내용은 golang에서 포인터 전달과 값 전달의 차이점은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!