Returning a value instead of a pointer in Go

huangapple go评论93阅读模式
英文:

Returning a value instead of a pointer in Go

问题

在Go语言的"net/http"包中,有一个名为ResponseWriter的接口。该接口有一个名为Header() Header的方法。由于Header()返回的Header值是一个值而不是指针,我假设该函数不会返回ResponseWriter私有的实际Header值,而是返回一个副本。

然而,事实并非如此。ResponseWriter的文档显示,使用r.Header().Add("key", "value")是向HTTP响应添加头部的正确方式。

我进一步深入研究了Header类型的定义。它是type Header map[string][]string。我有点困惑。在这种情况下,难道不需要返回指针才能修改ResponseWriter的值吗?如果是这样,为什么?

英文:

In the "net/http" package of Go, there is an interface called ResponseWriter. This interface has a method called Header() Header. Since the Header value that Header() returns is a value and not a pointer, I assumed the function would not be returning the actual Header value that is private to the ResponseWriter but rather a copy.

However, this does not appear to be the case. The docs for ResponseWriter show r.Header().Add("key", "value") to be the proper way to add a header to your http response.

I dug in a little deeper and found the definition for the Header type. It is type Header map[string][]string. I'm a little confused here. Do you not have to return a pointer in this case in order to modify the value that the ResponseWriter has? If so why?

答案1

得分: 4

这是因为地图(maps)和切片(slices)是引用类型。看一下这段代码:

package main

import (
	"fmt"
)

func main() {
	m1 := make(map[string]string)
	var m2 map[string]string
	m1["one"] = "this is from m1"
	m2 = m1
	m2["two"] = "this is from m2"
	fmt.Printf("%#v\n", m1)
}

输出结果是:

map[string]string{"one":"this is from m1", "two":"this is from m2"}

这段代码也会得到相同的结果:

package main

import (
	"fmt"
)

type mymap map[string]string

func main() {
	m1 := make(mymap)
	var m2 mymap
	m1["one"] = "this is from m1"
	m2 = m1
	m2["two"] = "this is from m2"
	fmt.Printf("%#v\n", m1)
}

输出结果是:

main.mymap{"one":"this is from m1", "two":"this is from m2"}

在 Go Playground 中查看/编辑

英文:

That's because maps and slices are reference types.
Take a look this code:

package main

import (
	"fmt"
)

func main() {
	m1 := make(map[string]string)
	var m2 map[string]string
	m1["one"] = "this is from m1"
	m2 = m1
	m2["two"] = "this is from m2"
	fmt.Printf("%#v\n", m1)
}

The output is:

map[string]string{"one":"this is from m1", "two":"this is from m2"}

See/edit in the Go Playground.

This has the same result:

package main

import (
	"fmt"
)

type mymap map[string]string

func main() {
	m1 := make(mymap)
	var m2 mymap
	m1["one"] = "this is from m1"
	m2 = m1
	m2["two"] = "this is from m2"
	fmt.Printf("%#v\n", m1)
}

Output:

main.mymap{"one":"this is from m1", "two":"this is from m2"}

See/edit in the Go Playground.

huangapple
  • 本文由 发表于 2016年4月16日 12:53:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/36660263.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定