3

I have been learning GO Lang for a month now. I have been coding in java for more than 4 years. In java the Request and Response both are object references. But, when it comes to GoLang the Response is a object reference and the Request is a Pointer Reference.

A reference, like a pointer, is an object that you can use to refer indirectly to another object. A reference declaration has essentially the same syntactic structure as a pointer declaration.

func hello(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Hello world!")
}

Apart from the readability perspective and the syntactic sugar is there any other intention behind using the Request as a pointer variable.

Adding to the above question the request here is an arbitrary pointer. i.e the request is not yet exists but the pointer is already referring to a memory location. Please throw some light if my understanding is wrong.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
wandermonk
  • 6,856
  • 6
  • 43
  • 93
  • 4
    there is no reference in golang, only pointer. and all parameters are passed by value. – zzn Jun 13 '17 at 05:32
  • @zzn i was not expecting an objective answer. Could you please take some of your valuable time to elaborate? – wandermonk Jun 13 '17 at 05:34
  • @zzn thank you i got the resource https://kuree.gitbooks.io/the-go-programming-language-report/content/26/text.html – wandermonk Jun 13 '17 at 05:51
  • 1
    As @zzn said: Go has absolutely no notion of "pass by reference" so it simply makes no sense to talk or reason about references in Go. Speculating about how Go would profit from "references" is pretty esoteric (as it won't happen). Several methods on `http.Request` modify the request thus require a pointer receiver thus requests are handled around as pointers everywhere. This is called consistency and has nothing to do with syntactic sugar or readability. – Volker Jun 13 '17 at 05:53
  • i don't really clear what's problem here. typically, if the value is too large to copy, or want to modify it, you should use pointer. golang actually a more safe language, pointer is not that dangerous. `r` is only a valid `http.Request` pointer or `nil`, no other cases. but in this case, only valid http.Request pointer actually. – zzn Jun 13 '17 at 05:53
  • 1
    Regarding the additional question "Please throw some light if my understanding is wrong." Yes, totally. Whether `r` points to some existing request or is nil (there are no other options) depends on how `hello` is called and on nothing else. To learn about pointers work through the Tour of Go starting from https://tour.golang.org/moretypes/1 – Volker Jun 13 '17 at 05:57
  • Possible duplicate of [In Go HTTP handlers, why is the ResponseWriter a value but the Request a pointer?](https://stackoverflow.com/questions/13255907/in-go-http-handlers-why-is-the-responsewriter-a-value-but-the-request-a-pointer) – Jack Wilsdon Feb 01 '19 at 00:23

2 Answers2

2

As correctly mentioned in many other answers here and elsewhere, ResponseWriter is an interface and the implications of this have beed described in detail in SO answers and blogs.

What I would like to address is what I feel is the big—and dangerous—misconception here, that the reason request is passed by "reference" (although such a thing does not really exist in Go) is that "we want to make changes to it visible to the server".

Quoting a couple of answers from other people:

[..]it's just a struct, and since we want to change this struct and have the web server see those changes, it has to be a pointer[..] SO

[..]changes to Request by the handler need to be visible to the server, so we’re only passing it by reference instead of by value [..] SO

This is wrong; in fact the docs explicitly warn against tampering with / mutating the request:

Except for reading the body, handlers should not modify the provided Request.

Quite the opposite, no? :-)

If you want to change the request, e.g. append a tracing header before passing it on to the next handler in a middleware chain you have to copy the request and pass the copied version down the chain.

Why use a pointer if we are explicitly telling people not to mutate the request? Performance, Request is a large struct and copying it can bring performance down, especially with long middleware chains in mind. The team had to strike a balance, definitely not an ideal solution, but the tradeoffs are clearly on the side of performance here (instead of API safety).

Community
  • 1
  • 1
joakim
  • 3,533
  • 2
  • 23
  • 28
1

Duplicate of In Go HTTP handlers, why is the ResponseWriter a value but the Request a pointer?

Mainly the ResponseWriter is an interface (you may want to understand more about interfaces, just in case you haven't gone over it). Just to add, the request is a pointer to a struct - there's no point in having a copy of the request struct (which happens when passed by value), so it's not passed as a struct (think of it esp. when you pass it downstream to other functions, you can just pass this down directly)

Ravi R
  • 1,692
  • 11
  • 16
  • Well thanks for pointing to the right source. http://www.airs.com/blog/archives/281 this blog made me more sense. – wandermonk Jun 13 '17 at 06:05
  • 3
    "ResponseWriter is an interface" is an important detail - it means that what you receive as the ResponseWriter _is also a pointer_. – Adrian Jun 13 '17 at 14:44