14.2. 프로그램언어 고(Go)에서의 포인터와 함수

프로그램언어 고(Go)의 함수에 포인터를 적용하는 방법

프로그램언어 고(Go)에서 함수에 포인터를 적용하는 방법은 다음과 같습니다.

package main

import "fmt"

func main() {

  var a int = 10
  
  // a 변수의 메모리 주소를 p에 할당
  p := &a
  
  // p를 이용해 a 변수의 값 출력
  fmt.Println(*p) 
}

위의 예제코드에서 보시다시피, 변수 a를 선언하고 그 변수의 메모리 주소를 p 포인터 변수에 할당합니다.
이렇게 하면 p는 a 변수의 메모리 주소를 가리키는 포인터가 됩니다.

그리고 *p 문법을 사용하여 p 포인터가 가리키는 메모리의 값에 접근할 수 있습니다.
즉, *p는 a 변수의 값과 동일하다고 보시면 됩니다.

이를 통해 함수 내에서 변수의 메모리 주소를 가리키는 포인터를 사용함으로써, 함수 밖의 변수에 접근할 수 있습니다.

package main

import "fmt"

func change(num *int) {
  *num = 20 // 포인터를 이용해 함수 밖의 변수 변경
}

func main() {

  var a int = 10

  fmt.Println("Before: ", a)

  change(&a) // a 변수의 메모리 주소 전달

  fmt.Println("After: ", a)  
}

위의 예제에서 change 함수가 int 포인터를 매개변수로 받아서, 이를 이용해 함수 밖의 a 변수를 변경합니다.

즉, *num = 20 은 main 함수의 a 변수의 값을 20으로 변경하는 코드라고 보시면 됩니다.

이처럼 고(Go)에서는 함수에 포인터 매개변수를 이용하여 함수 밖의 변수를 참조하고 수정할 수 있습니다.

물론 반환값으로 포인터를 사용하는 방법도 있습니다.

이상으로 고(Go)의 함수에서 포인터 적용 방법에 대해 간략하게 설명드렸습니다. 포인터는 다소 복잡한 개념이기 때문에 예제 코드와 함께 반복적으로 연습하는 것이 중요합니다.

프로그램언어 고(Go)에서의 함수 포인터 작성과 활용

고(Go)언어에서 함수 포인터는 함수를 가리키는 포인터 변수입니다. 이를 사용하면 함수를 파라미터로 전달하거나 함수의 주소를 저장 및 전달할 수 있습니다.


package main

import "fmt"

// 함수 정의
func add(a, b int) int {
    return a + b
}

func main() {

    // 함수 포인터 변수 선언 
    var f func(int, int) int

    // 함수의 주소를 포인터에 저장
    f = add

    // 함수 포인터를 통해 함수 호출
    result := f(1, 2)
    fmt.Println(result) 
}

위 예제에서 add 함수의 주소를 f 함수 포인터 변수에 저장합니다.
그리고 나중에 f를 통해 저장된 함수를 호출할 수 있습니다.

함수 포인터의 장점은 다음과 같습니다.

1. 함수를 파라미터로 전달할 수 있음
2. 콜백 함수 구현 시 유용
3. 함수의 주소 저장/전달 가능

예를 들어, 여러 함수를 파라미터로 받아서 호출 가능한 함수를 만들 수 있습니다.


func execute(f func()) {
    f() 
}

func printHello() {
    fmt.Println("Hello") 
}

func main() {
    execute(printHello)
}

execute 함수가 printHello 함수의 주소를 받아서 호출하는 예제입니다.

또한 콜백 함수를 구현할 때도 함수 포인터가 유용합니다.


func process(data []int, f func(int)) {
    for _, v := range data {
        f(v)
    }
}   

func printInt(x int) {
    fmt.Println(x)
}

func main() {  
    data := []int{1, 2, 3}
    process(data, printInt) 
}

process 함수가 데이터 배열과 콜백 함수를 파라미터로 받아서 콜백 함수를 데이터에 적용하는 예제입니다.

이처럼 고(Go)언어의 함수 포인터는 다양한 유용한 응용이 가능합니다. 매우 중요하고 활용도가 높은 기능이므로 꼭 숙지하시기 바랍니다.

프로그램언어 고(Go)에서의 포인터 인자를 가진 함수

package main

import "fmt"

func double(x *int) {
    *x *= 2 
}

func main() {
    x := 10
    double(&x)
    fmt.Println(x) // 20
}

고(Go)언어에서 함수 인자로 포인터를 사용하는 경우는 값에 의한 전달이 아닌 참조에 의한 전달을 하기 위함입니다.

위의 예제 코드에서 double 함수는 매개변수로 int형 포인터 x를 받아 그 참조값에 2를 곱합니다.
main 함수에서는 변수 x의 주소값 &x를 double 함수에 전달합니다.

따라서 double 함수 내에서 x 포인터의 값을 변경하면, main 함수의 x 변수의 값도 변경됩니다.

즉, 참조에 의한 전달을 통해 함수 밖의 변수값을 함수 내부에서 직접 변경할 수 있게 됩니다.

이는 값에 의한 전달인 경우 함수 인자값을 변경해도 함수 밖의 변수에 영향을 주지 않는 것과 대비됩니다.

포인터 인자를 사용하는 장점은 성능 향상으로, 큰 데이터를 전달할 때 메모리 복사 없이 참조 값만 전달하여 처리 속도를 높일 수 있다는 것입니다.

하지만 참조에 의한 데이터 접근을 허용하기 때문에, 함수 밖의 데이터를 변경할 수 있으므로 지역적이지 않고 변수 상태 관리가 복잡할 수 있다는 단점도 있습니다.

따라서 포인터 인자 사용 시 참조한 데이터의 lifetime과 변경 가능성을 신중히 고려해야 합니다.

이상으로 고(Go)언어에서의 포인터 인자를 가진 함수에 대해 설명 드렸습니다. 더 궁금하신 점이 있으시면 언제든 질문 부탁드리겠습니다.

프로그램언어 고(Go)에서의 포인터 리턴을 가진 함수

제가 Go언어의 포인터 리턴을 가진 함수에 대해 한글로 최대한 친절하고 상세하게 설명드리겠습니다.

Go언어에서 포인터를 리턴하는 함수는 실제 변수의 메모리 주소를 리턴합니다. 이를 통해 함수 외부에서 실제 변수를 참조하고 수정할 수 있게 됩니다.


package main

import "fmt"

func returnPointer() *int {
  i := 5 
  return &i
}

func main() {
  p := returnPointer()
  fmt.Println(*p) 

  *p = 10
  fmt.Println(*p)
}

위의 예제코드에서 returnPointer() 함수가 int형 변수 i의 포인터를 리턴합니다.
main() 함수에서 이 포인터 p를 받아서 역참조하여 값을 출력하거나, 포인터를 통해 값을 변경할 수 있습니다.

즉, 포인터를 리턴받으면 함수 내부의 실제 변수에 접근할 수 있다는 장점이 있습니다.

하지만 함수가 종료되면 지역 변수인 i가 사라지기 때문에, 리턴된 포인터는 주소는 있지만 실제 변수는 존재하지 않는 상태가 됩니다.

따라서 포인터 리턴 사용 시 주의가 필요합니다. 보통 아래와 같은 경우에 유용하게 사용할 수 있습니다.

– 큰 구조체를 리턴할 때 메모리 복사 오버헤드를 피하고자 할 때
– 특정 데이터를 함수 외부에서 공유 변경할 필요가 있을 때

이외에도 다양한 목적으로 사용되고 있습니다.

포인터 리턴 시 주의사항을 잘 숙지하고, 상황에 맞게 적절하게 사용한다면 효율적인 코딩이 가능합니다.

위 설명이 도움이 되었기를 바랍니다.

프로그램언어 고(Go)에서의 포인터를 이용한 함수 호출

프로그램언어 고(Go)에서 포인터를 이용한 함수 호출은 값에 의한 호출과 참조에 의한 호출을 구분할 때 중요합니다.

값에 의한 호출은 함수 인자로 변수의 값 자체를 전달하며, 참조에 의한 호출은 함수 인자로 변수의 메모리 주소, 즉 포인터를 전달합니다.

package main

import "fmt"

func value(b int) {
    b = 20
}

func reference(b *int) {
    *b = 20  
}

func main() {

    var a int = 10

    value(a)
    fmt.Println(a) // 10

    reference(&a)
    fmt.Println(a) // 20

}

위의 예제코드를 보면, value() 함수는 인자로 전달받은 변수 b의 값 자체를 변경합니다.

main() 함수에서 호출 시 전달하는 변수 a의 값은 함수 호출 후에도 변하지 않습니다.

반면 reference() 함수는 인자로 변수의 메모리 주소인 포인터를 받습니다.

포인터 연산자(*)를 사용하여 해당 메모리 주소의 실제 값을 변更합니다.

따라서 main() 함수의 변수 a 값이 실제로 변경됩니다.

이처럼 고(Go)에서는 포인터를 사용하여 참조에 의한 호출을 하면 함수 내에서 호출元 변수의 실제 값을 변경할 수 있습니다.

주의할 점은 참조에 의한 호출 시 변수 주소를 함수 인자로 넘겨야한다는 것입니다.

&연산자를 사용하여 변수의 메모리 주소인 포인터를 얻고 이를 함수에 전달합니다.

이러한 참조에 의한 호출은 다른 함수나 메서드에서 직접 주어진 변수의 값을 수정하고자 할 때 유용하게 사용할 수 있습니다.

Leave a Comment