函数参数,带*和不带*的区别

1
2
3
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
	DefaultServeMux.HandleFunc(pattern, handler)
}

为什么 ResponseWriter 不带 * ,Request 带 *,什么时候带?什么时候不带呢?

在Go语言中,函数参数的语法规则是由类型名称和类型修饰符组成的。类型修饰符 “*” 表示指针类型,用于指向某个类型的指针。在函数签名中,类型修饰符的位置决定了传递参数的方式。

HandleFunc函数中,ResponseWriter没有使用指针类型修饰符"*",而Request使用了指针类型修饰符"*"。这是因为ResponseWriterRequest是不同的类型,并且在函数中对它们的处理方式也不同。

ResponseWriter是一个接口类型,它定义了用于构建HTTP响应的方法。在HandleFunc函数中,我们通常不需要修改ResponseWriter的内部状态,因此将其作为普通值传递给函数即可。

Request是一个结构体类型,用于表示HTTP请求的各个属性。在处理HTTP请求时,我们通常需要修改Request的内部状态,例如解析请求参数、修改请求头等。为了避免复制整个结构体,我们将Request作为指针传递给函数,这样函数可以直接修改原始数据。

总结起来,当我们对函数参数进行修改操作时,通常使用指针类型(使用"*“修饰符),而当我们只需要读取参数或不修改参数时,可以使用普通值类型。这样可以提高性能并避免不必要的内存开销。

我理解只读取也可以用*,而且不需要复制整个结构体了

您对于只读取而不修改参数的情况下使用指针是正确的。使用指针类型可以避免将整个结构体复制到函数的栈帧中,从而提高性能和节省内存。

在Go语言中,可以将指针作为参数传递给函数,以便在函数内部只读取结构体的内容。这样做可以避免复制整个结构体,而只是传递指向结构体的指针,从而减少内存开销。

例如,如果您有一个函数如下:

1
2
3
func ReadData(data *SomeStruct) {
    // 读取data的内容,但不修改它
}

在这个函数中,data是指向SomeStruct类型的指针。通过传递指针作为参数,函数可以直接读取SomeStruct的内容,而无需复制整个结构体。这对于大型结构体或需要频繁读取的情况下特别有用。

需要注意的是,当我们使用指针作为函数参数时,需要确保在函数内部不会修改指针所指向的数据。如果在函数内部修改了指针所指向的数据,这种修改将对调用方可见,可能会引发意外的副作用。因此,在只读取而不修改参数的情况下使用指针时,需要特别小心确保不会对数据进行修改。

看着是 * 能够满足所有情况,但 * 要关心别把不需要改的给改了。

0%