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

Golang 기본 튜토리얼

Golang 제어문

Golang 함수 & 메서드

Golang 구조체

Golang 슬라이스 & 배열

Golang 문자열(String)

Golang 포인터

Golang 인터페이스

Golang 동기

Golang 예외(Error)

Golang 기타杂项

Go 언어 포인터

Go 프로그래밍 언어의 포인터는 다른 변수의 메모리 주소를 저장하는 변수입니다. Golang의 포인터는 특수 변수라고도 합니다.변수특정 데이터가 시스템의 특정 메모리 주소에 저장되는 데 사용됩니다. 항상 16진수 형식으로 메모리 주소를 찾습니다(0x로 시작하여 0xFFAAF와 같은 형식).

포인터의 역할?
이런 포인터를 이해하려면, 먼저 변수 개념을 이해해야 합니다. 변수는 실제 데이터 저장 위치에 이름을 부여하는 것입니다. 저장된 데이터에 접근하기 위해, 특정 저장 위치의 주소가 필요합니다. 모든 메모리 주소(16진수 형식)를 수동으로 기억하는 것은 비용이 크기 때문에, 우리는 데이터를 저장하고, 변수 이름만 사용하여 변수에 접근할 수 있는 이유입니다.
Golang은 16진수를 변수에 저장하는 데 글자 표현식을 사용할 수 있습니다. 즉,0x시작하는 숫자는 16진수입니다.

예제:아래의 프로그램에서는 16진수를 변수에 저장할 것입니다. 그러나 값의 타입이int또는 다른 말로 말해서, 10진수로 저장되었습니다.int타입의 십진값이 저장되고 있습니다. 그러나, 이 예제를 설명하는 주요 포인트는 우리가 저장하는 것이 16진수 값(메모리 주소로 간주)이지만, 그것은 다른 변수의 어떤 다른 메모리 위치를 가리키지 않기 때문에 포인터가 아니라는 것입니다. 그것은 단순히 사용자 정의 변수입니다. 따라서 이것을 위해 포인터가 필요합니다.

//16진수 값을 저장
package main
import "fmt"
func main() {
    //16진수 저장
    //변수에 저장된 값
    x := 0xFF
    y := 0x9C
    // 표시 값
    fmt.Printf("변수 x의 타입은 %T\n", x)
    fmt.Printf("x의 십육진 값은 %X\n", x)
    fmt.Printf("x의 십진값은 %v\n", x)
    fmt.Printf("변수 y의 타입은 %T\n", y)
    fmt.Printf("y의 십육진 값은 %X\n", y)
    fmt.Printf("y의 십진값은 %v\n", y)
}

출력:

변수 x의 타입은 int입니다
x의 십여진 값은 FF
x의 십진 값은 255
변수 y의 타입은 int입니다
y의 십여진 값은 9C
y의 십진 값은 156

포인터는 다른 변수의 메모리 주소를 저장하는 특별한 변수로, 메모리 위치를 가리키며 그 위치에 저장된 값을 찾는 방법을 제공합니다. 일반 변수와 거의 같이 선언되지만,*(도메인 연산자)。

포인터 선언 및 초기화

시작하기 전에, 포인터에서 두 가지 중요한 연산자를 사용하겠습니다.

*연산자 도메인 연산자로, 포인터 변수를 선언하고 주소에 저장된 값을 접근하는 데 사용됩니다.

& 연산자 도메인 연산자로, 변수의 주소를 반환하거나 변수의 주소를 포인터에 접근하는 데 사용됩니다.

포인터를 선언합니다:

var pointer_name *Data_Type

예제:다음은 문자열 타입의 포인터입니다. 이 포인터는 다음과 같은 타입의 값을 저장할 수 있습니다문자열변수의 메모리 주소.

var s *string

포인터 초기화:이를 위해, 다른 변수의 메모리 주소를 초기화하는 데 사용하는 주소 연산자를 사용해야 합니다. 다음 예제와 같이:

//일반 변수 선언
var a = 45
//이를 통해 포인터 s를 초기화합니다
//변수 a의 메모리 주소
var s *int = &a
// Golang 프로그램을 통해 선언을 보여줍니다
//및 포인터의 초기화
package main
import "fmt"
func main() {
    //일반 변수 정의
    var x int = 5748
    //포인터 선언
    var p *int
    //포인터 초기화
    p = &x
    //결과 표시
    fmt.Println("x에 저장된 값 = ", x)
    fmt.Println("x의 메모리 주소 = ", &x)
    fmt.Println("변수 p에 저장된 값 = ", p)
}

출력:

x에 저장된 값 =  5748
x의 메모리 주소 = 0xc000066090
변수 p에 저장된 값 = 0xc000066090

중요 사항:

  • 포인터의 기본 값이나 zero 값은 항상 nil입니다. 또는, 초기화되지 않은 포인터는 항상 nil 값을 가질 수 있습니다.

    //포인터의 nil 값
    package main
    import "fmt"
    func main() {
        //포인터 정의
        var s *int
        // 결과 표시
        fmt.Println("s = ", s)
    }

    출력:

    s = <nil>
  • 포인터의 선언과 초기화는 한 줄에서 완료할 수 있습니다.

    var s *int = &a
  • 데이터 타입과 포인터 선언을 동시에 지정하려면, 포인터는 지정된 데이터 타입 변수의 메모리 주소를 처리할 수 있습니다. 예를 들어, 문자열 타입의 포인터를 사용하면 포인터에 제공되는 변수의 주소는 문자열 데이터 타입 변수만이 아니라 다른 어떤 타입도 아닙니다.

  • 위의 문제를 극복하기 위해 사용할 수 있습니다var 키워드의 타입 추론 개념입니다. 선언 중 데이터 타입을 지정할 필요가 없습니다. 포인터 변수의 타입도 일반 변수와 마찬가지로 컴파일러가 결정할 수 있습니다. 여기서는 사용하지 않을*다른 변수의 주소를 초기화할 때, 컴파일러는 내부적으로 변수가 포인터 변수라고 결정합니다。

    // Golang 프로그램을 통해 보여줍니다
    //연산자
    //포인터 변수
    package main
    import "fmt"
    func main() {
        //var 키워드를 사용하여
        //우리는 정의하지 않았습니다
        //변수를 포함한 모든 타입
        var y = 458
        //포인터 변수를 사용하여
        // var 키워드는 타입을 지정하지 않습니다
        //타입
        var p = &y
        fmt.Println("y에 저장된 값 = ", y)
        fmt.Println("y의 주소 = ", &y)
        fmt.Println("포인터 변수 p에 저장된 값 = ", p)
    }

    출력:

    y에 저장된 값을 저장된  458
    y의 주소 = 0xc0000120a8
    포인터 변수 p에 저장된 값 = 0xc0000120a8
  • 중에서 타입 추론을 사용할 수도 있습니다단축(:=)문법을 사용하여 포인터 변수를 선언하고 초기화합니다。&(주소)연산자가 변수의 주소를 전달하면, 컴파일러는 내부적으로 해당 변수가 포인터 변수라고 결정합니다。

    // Golang 프로그램을 통해 보여줍니다
    //에서 줄이기语法을 사용하여
    //포인터 변수
    package main
    import "fmt"
    func main() {
        //:= 연산자를 사용하여 선언
        //변수를 초기화합니다
        y := 458
        //포인터 변수를 사용하여
        //:=를 통해 할당됩니다
        //변수 y의 주소
        p := &y
        fmt.Println("y에 저장된 값 = ", y)
        fmt.Println("y의 주소 = ", &y)
        fmt.Println("포인터 변수 p에 저장된 값 = ", p)
    }

    출력:

    y에 저장된 값을 저장된  458
    y의 주소 = 0xc000066090
    포인터 변수 p에 저장된 값 = 0xc000066090

pointer dereference

众所周知,*연산자는 해제 연산자로도 알려져 있으며, 포인터 변수를 선언하는 데 사용되지 않을 뿐만 아니라, 포인터가 가리키는 변수에 저장된 값을 접근하는 데도 사용되며, 일반적으로간접적이거나 해제*연산자는 주소의 값을 의미합니다。이 개념을 더 잘 이해하기 위해 예제를 들어보겠습니다:

// Golang 프로그램 예제
//포인터 해제(concept)의 개념
package main
import "fmt"
func main() {
    //var 키워드를 사용하여
    //우리는 정의하지 않았습니다
    //변수를 포함한 모든 타입
    var y = 458
    //포인터 변수를 사용하여
    // var 키워드는 타입을 지정하지 않습니다
    //타입
    var p = &y
    fmt.Println("y에 저장된 값 = ", y)
    fmt.Println("y의 주소 = ", &y)
    fmt.Println("포인터 변수 p에 저장된 값 = ", p)
    //이는 포인터의 해제(ref)입니다
    //포인터 앞에서 사용*연산자
    //변수를 통해 저장된 값을 접근
    //그것이 가리키는 변수를 가리키는
    fmt.Println("y에 저장된 값을 저장된*p) = ", *p)
}

출력:

y에 저장된 값을 저장된  458
y의 주소 = 0xc0000120a8
포인터 변수 p에 저장된 값 = 0xc0000120a8
y에 저장된 값을 저장된*p) =  458

포인터의 값을 변경하거나 메모리 위치를 변경할 수도 있으며, 새 변수를 할당하지 않아도 됩니다.

package main
import "fmt"
func main() {
    //var 키워드를 사용하여
    //우리는 정의하지 않았습니다
    //변수 타입을 지정하지 않았습니다
    var y = 458
    //포인터 변수를 사용하여
    // var 키워드는 타입을 지정하지 않습니다
    var p = &y
    fmt.Println("변경전에 저장된 y에 저장된 값 = ", y)
    fmt.Println("y의 주소 = ", &y)
    fmt.Println("포인터 변수 p에 저장된 값 = ", p)
    //이는 포인터의 해제(ref)입니다
    //포인터 앞에서 사용*연산자
    //변수를 통해 저장된 값을 접근
    //그것이 가리키는 변수를 가리키는
    fmt.Println("변경전에 저장된 y(*p)에 저장된 값 = ", *p)
    //y의 값을 변경하는 코드
    //포인터의 새 값
    *p = 500
    fmt.Println("변경后被 저장된 y(*p)에 저장된 값 = ", y)
}

출력:

변경전에 저장된 y에 저장된 값 =  458
y의 주소 = 0xc0000120a8
포인터 변수 p에 저장된 값 = 0xc0000120a8
변경전에 저장된 y(*p)의 값 =  458
변경后被 저장된 y(*p)의 값 =  500