Go(golang)에서 포인터의 적절한 사용

4325 단어 programminggotutorial
Go는 최근 몇 년 동안 특히 우리 지역에서 점점 인기를 얻고 있습니다. Go는 지속적으로 Ruby, Python, C# 및 Java와 같은 다른 백엔드 언어를 대체해 왔습니다. Go는 단순성, 명확성, 속도 및 낮은 메모리 소비로 인해 필요합니다.

언어를 처음 접하거나 포인터를 사용하여 메모리를 직접 처리할 수 있는 언어를 처음 접하는 많은 개발자는 결국 해당 포인터를 오용하게 됩니다.

포인터란?



포인터는 값 자체가 아니라 값의 주소를 저장하는 변수입니다. 컴퓨터의 메모리(RAM)를 JSON 객체로 생각하면 포인터는 키, 일반 변수는 값이 될 것입니다.

{
  "pointer": "variableValue"
}


실제로 작동하는 것을 볼 수 있습니다.

package main

import "fmt"

func main() {
        // create a normal string variable
    name := "original"
        // pass in a pointer to the string variable using '&'
    setName(&name, "qvault")
    fmt.Println(name)
}

func setName(ptr *string, newName string) {
        // dereference the pointer so we can modify the value
        // and set the value to "qvault"
    *ptr = newName
}


다음이 인쇄됩니다.

qvault


보시다시피 변수_,_의 주소에 대한 포인터가 있기 때문에 다른 함수의 범위 내에서도 값을 수정할 수 있습니다. 값이 포인터가 아니면 작동하지 않습니다.

package main

import "fmt"

func main() {
    name := "original"
    setNameBroken(name, "qvault")
    fmt.Println(name)
}

func setNameBroken(ptr string, newName string) {
    ptr = newName
}


인쇄물:

original


포인터는 유용할 수 있지만 유용한 것과 마찬가지로 위험할 수도 있습니다. 예를 들어 값이 없는 포인터를 역참조하면 프로그램이 패닉 상태가 됩니다. 이러한 이유로 인쇄를 시도하기 전에 항상 오류 값이 nil인지 확인합니다.

통사론



1. 포인터 만들기: &

newString := ""
newStringPointer := &newString


해당 포인터를 인쇄하면 메모리 주소가 표시됩니다.

package main

import "fmt"

func main() {
    newString := ""
    newStringPointer := &newString
    fmt.Println(newStringPointer)
}


인쇄: 0xc00000e1e0

컴퓨터에서 해당 변수의 메모리 주소는 무엇입니까?

2. 포인터 설명: *

함수 서명 또는 유형 정의에서 *는 값이 포인터임을 지정하는 데 사용됩니다.

func passPointer(pointer *string) {
}


3. 포인터 역참조: *

약간 혼란스러울 수 있지만 *는 포인터를 설명하는 데 사용되며 포인터를 역참조하는 연산자로도 사용됩니다.

func derefPointer(pointer *string) {
    newStringVariable := *pointer
        // newStringVariable is just a normal string
}


언제 포인터를 사용해야 합니까?



포인터가 좋은 아이디어인 경우 미묘한 차이가 많을 수 있지만 포인터를 사용하는 시간의 95%는 다음 이유 중 하나여야 합니다.

1. 매개변수 중 하나를 변경하는 함수

포인터를 인수로 사용하는 함수를 호출할 때 내 변수가 변경될 것으로 예상합니다. 함수에서 변수를 변경하지 않는 경우 포인터를 사용하지 않아야 합니다.

2. 더 나은 성능



메모리에 전체 소설을 포함하는 문자열이 있는 경우 새 함수에 전달될 때마다 해당 변수를 복사하는 데 비용이 많이 듭니다. 대신 CPU와 메모리를 절약할 수 있는 포인터를 전달하는 것이 좋습니다. 그러나 이것은 가독성을 희생시키므로 필요한 경우에만 이 최적화를 수행하십시오.

3. Nil 값 옵션이 필요합니다.

때때로 함수는 어떤 것의 값이 무엇인지, 그것이 존재하는지 여부를 알아야 합니다. 필드가 존재하는지 여부를 알기 위해 JSON을 읽을 때 일반적으로 이것을 사용합니다. 예를 들어 JSON 객체가 다음과 같은 경우:

{ "name": "qvault" } ----> *name: "qvault"

{ "name": "" } ----------> *name: ""

{} ----------------------> *name: nil


감사



다음은 코드에서 포인터를 사용하는 경우에 대한 몇 가지 경험 법칙입니다. 확실하지 않고 정상 값이 제대로 작동하는 경우 포인터를 사용하지 않는 것이 좋습니다. 포인터는 유용한 도구이지만 매우 쉽게 불쾌한 버그나 읽을 수 없는 코드로 이어질 수 있습니다.

레인 와그너

Qvault 다운로드: https://qvault.io

Github 별표: https://github.com/q-vault/qvault

게시물 The Proper Use of Pointers in Go (golang)Qvault에 처음 나타났습니다.

좋은 웹페이지 즐겨찾기