Go 语言(golang)中指针的正确使用方法
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
近年来,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. 需要一个零值选项
有时函数需要知道某个元素的值以及它是否存在。我通常在读取 JSON 数据时使用这种方法来判断某个字段是否存在。例如,如果一个 JSON 对象是:
{ "name": "qvault" } ----> *name: "qvault"
{ "name": "" } ----------> *name: ""
{} ----------------------> *name: nil
谢谢
以下是一些关于何时在代码中使用指针的经验法则。如果您不确定,并且使用普通值也能正常工作,我建议您避免使用指针。指针虽然很有用,但也很容易导致严重的错误或代码难以阅读。
作者:Lane Wagner @wagslane
下载 Qvault:https://qvault.io
请为我们的 GitHub 仓库点赞:https://github.com/q-vault/qvault
文章《Go语言(golang)中指针的正确使用》最初发表于Qvault。
文章来源:https://dev.to/bootdotdev/the-proper-use-of-pointers-in-go-golang-42ob
