English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Golang 기본 튜토리얼

Golang 제어문

Golang 함수 & 메서드

Golang 구조체

Golang 슬라이스 & 배열

Golang 문자열(String)

Golang 포인터

Golang 인터페이스

Golang 동기

Golang 예외(Error)

Golang 다른 항목

Go 언어 함수가 포인터를 반환

Golang 프로그래밍 언어에서 포인터는 다른 변수의 메모리 주소를 저장하는 변수입니다. 함수에 포인터를 전달할 수 있으며, Golang 함수에서 포인터를 반환할 수 있습니다. C/ c++에서는 함수 외부에서 지역 변수의 주소를 반환하는 것을 권장하지 않습니다. 왜냐하면 함수가 반환된 후 그 주소는 범위를 벗어났기 때문입니다. 따라서 C/ c++C에서 함수가 포인터를 반환하는 경우, 지역 변수를 정적 변수로 정의해야 합니다.

예제:먼저 C를 보여드리겠습니다.++예를 들어, 아래 프로그램의 코드 행( int lv = n1 * n1;)을 경고로 출력합니다. 경고를 피하기 위해 정적 변수로 설정하세요.

// C ++프로그램이 반환
//함수에서의 포인터
#include <iostream> 
using namespace std; 
  
//포인터로 반환 타입을 가진 값을 받아들입니다
int* rpf(int); 
  
int main() 
{ 
  
    int n = 745; 
  
    //n의 값을 표시
    cout << n << endl; 
  
    //함수 호출
    cout << *rpf(n) << endl; 
} 
  
//함수 정의 
int* rpf(int n1) 
{ 
  
        //지역 변수를 가져옵니다
        //함수 내에서
    int lv = n1 * n1; 
  
        
    // static int lv = n1 * n1; 
  
    //C++ 에서 이를 통해 경고가 발생합니다
    //주소 반환
    return &lv; 
}

경고 사항

prog.cpp: 함수 ‘int* rpf(int)’:
prog.cpp:24:9: warning: address of local variable ‘lv’ returned [-Wreturn-local-addr]
int lv = n1 * n1;

출력:

745

이 경우의 주요 원인은 컴파일러가 항상 함수 호출에 대해 스택을 생성한다는 것입니다. 함수가 종료되면 함수 스택도 제거되고, 이는 함수의 지역 변수가 범위를 벗어나는 원인이 됩니다. 이를 정적으로 설정하면 문제를 해결할 수 있습니다. 정적 변수는 범위를 벗어났을 때도 그 값을 유지하는 특성을 가지고 있습니다.

하지만Go 컴파일러는 매우 지능적입니다!스택에 메모리를 할당하지 않습니다. 이 함수의 지역 변수에 대한 메모리를 할당하면, 이 변수는 힙에 할당됩니다. 아래 프로그램에서 변수lv스택에 메모리를 할당하지 않고, Go 컴파일러가 변수를 로컬 범위에서 탈출시키기 위해 이스케이프 분석을 수행하므로 힙에 메모리를 할당합니다.

//Go 함수는 포인터를 반환
package main
import "fmt"
func main() {
    //함수 호출
    n := rpf()
    //값을 표시
    fmt.Println("n의 값: ", *n)
}
//정수를 가진 함수 정의
//포인터로 반환 타입
func rpf() *int {
    //지역 변수
    //함수 내에서 간단한 연산자로 변수를 선언
    lv := 100
    // lv의 주소를 반환
    return &lv
}

출력:

n의 값:  100

주의: Golang은 C와 같이 / C ++이러한 포인터 알고리즘의 어떤 지원도 제공하지 않습니다. 실행하면 컴파일러가 오류를 발생시키고, 무효한 작업으로 간주합니다.

관련 지식: Go에서포인터포인터를 함수로 전달