포인터는 좋은 코드를 작성하는 데 있어 가장 중요한 부분 중 하나입니다. 이 글에서는 포인터가 무엇이고 Go에서 포인터를 사용하는 방법을 살펴보겠습니다.
포인터는 가리키는 주소를 저장하는 변수입니다(강조하자면 숫자 값을 저장하는 변수일 뿐입니다). [관련 권장사항: Go 동영상 튜토리얼]
특정 유형의 포인터는 해당 유형만 가리킬 수 있습니다(포인터가 가리키는 데이터 유형은 변경할 수 없습니다).
포인터 구문은 매우 간단합니다. 다음은 Go의 포인터 선언 구문입니다.
var ptr *type var ptrint *int // 指向 int 的指针
포인터의 0 값은 nil입니다.
유형 포인터는 &
를 사용하여 초기화됩니다. &
对其进行初始化:
package main import ( "fmt" ) func main() { var q int = 42 var p *int // declare the pointer p = &q // initialize the pointer fmt.Println(p) // 0x40e020 }
指针取值意味着获取指针保存的地址内的值。下面是使用 *
运算符执行指针取值操作的示例:
package main import ( "fmt" ) func main() { var q int = 42 var p *int p = &q fmt.Println(p) // 0x40e020 fmt.Println(*p) // 42 }
指针的地址为一个数值,此数值也可以被赋值给其他变量。因此,我们可以创建间接级别。这些间接级别有时会产生不必要的混淆,所以请谨慎使用。
package main import ( "fmt" ) func main() { i := 64 j := &i // j 是 int 类型的指针 k := &j // k 是存放指针地址的指针,也是 int 类型 fmt.Println(i) // 64 fmt.Println(j) // 0x40e020 fmt.Println(*j) // 64 (value inside that address) fmt.Println(k) // 0x40c138 fmt.Println(*k) // 0x40e020 (address of j) }
指针可以指向任何东西,甚至可以指向接口。当使用空接口时,返回的值为 nil。
package main import ( "fmt" ) func main() { var a interface{} b := &a fmt.Println(b) // 0x40c138 fmt.Println(*b) // <nil> }
下面是一个使用带有指针接口的例子。
package main import ( "fmt" ) // 定义接口 type Bird interface{ fly() } type B struct{ name string } // 实现它 func (b B)fly() { fmt.Println("Flying...") } func main() { var a Bird = B{"Peacock"} b := &a fmt.Println(b) // 0x40c138 fmt.Println(*b) // {Peacock} }
这里 “a” 是一个 struct 类型的 Bird,然后用于接口类型,如您所见。这就是多态的使用。Go 允许使用 接口来实现多态. 因此,您可以看到指向结构或接口的指针是 Go 中必不可少的工具。
指针可以在 函数 中作为参数使用。与直接使用值相比,它有一些优势。使用指针作为参数是将大对象传递给函数的一种非常有效的方式。因此,使用它是一个巨大的优化。
package main import ( "fmt" ) //声明指针参数 func f(a *int) { fmt.Println(*a) } func main() { var a int = 42 // 传递地址 f(&a) // 42 }
使用大型对象可以减缓执行时间,这是将指针传递给结构体的示例。这是处理大对象的有效方法。
package main import ( "fmt" ) type Human struct { name string age int place string } func f(h *Human) { fmt.Println("The user", (*h).name, "is", (*h).age, "years old and he is from", (*h).place) } func main() { john := Human{"John", 36, "Las Vegas"} f(&john) // The user John is 36 years old and he is from Las Vegas }
取消引用结构时要小心。如果您使用它像 *structname.field1
那么它会抛出错误。 正确的方法是 (*structname).field1
package main import ( "fmt" ) func main() { ptri := new(int) *ptri = 67 fmt.Println(ptri) // 0x40e020 fmt.Println(*ptri) // 67 }
*
연산자를 사용하는 예입니다: package main import ( "fmt" ) func p() *int { // 将返回类型指定为指针 v := 101 // 返回地址 return &v } func main() { n := p() fmt.Println(n) // 0x40e020 fmt.Println(*n) // 101 }
포인터의 주소는 숫자 값이며, 이 숫자 값은 다른 변수에도 할당될 수 있습니다. 따라서 간접 수준을 만들 수 있습니다. 이러한 간접적인 수준은 때때로 불필요한 혼란을 야기할 수 있으므로 주의해서 사용하십시오.
package main import ( "fmt" ) func main() { f := func() { fmt.Println("a function") } pf := f pf() // 一个函数 }
입니다.
here
"a"
포인터는 함수
*structname.field1
과 같이 사용하면 오류가 발생합니다. 🎜올바른🎜방법은 (*structname).field1
입니다. 🎜🎜함수 내에서 포인터를 사용하면 매개변수가 🎜const🎜가 아닌 한 값이 "🎜mutable🎜"이 됩니다. 따라서 값을 변경하고 싶을 때마다 해당 값에 대한 포인터를 함수 매개변수로 사용해야 합니다. 그런 다음 필요한 변경을 수행해야 합니다. . 🎜🎜🎜8. Go의 "new" 함수 🎜🎜🎜 Go의 🎜new🎜 함수는 유형에 대한 포인터를 반환합니다. 🎜🎜rrreee🎜🎜🎜9. 함수에서 포인터 반환 🎜🎜🎜 다른 값과 마찬가지로 모든 유형의 포인터가 함수에서 반환될 수 있습니다. 정말 간단합니다. 값을 직접 반환하지 않고 값의 주소를 반환합니다. 🎜🎜rrreee🎜🎜🎜10. 함수에 대한 포인터 🎜🎜🎜함수에 대한 포인터는 Go에서 암시적으로 작동합니다. 즉, 포인터로 선언할 필요가 없습니다. 🎜🎜rrreee🎜🎜🎜11. Go에서 포인터를 사용할 때 기억해야 할 사항🎜🎜🎜Go에서는 포인터 연산이 허용되지 않습니다. 따라서 C/C++에서 할 수 있는 단항 증가 또는 감소와 같은 작업을 수행할 수 없습니다. 🎜배열에 대한 포인터를 사용하고 싶을 수도 있지만 슬라이스를 사용하는 것이 더 나은 옵션입니다. 슬라이스는 배열에 대한 포인터보다 훨씬 더 다양합니다. 코드는 매우 간결하며 작업을 더 쉽게 만듭니다. 따라서 가능하면 슬라이스를 사용하십시오. 🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 비디오🎜를 방문하세요! ! 🎜
위 내용은 Go 언어 포인터에 대한 11가지 지식 포인트에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!