I was defining a func getIPAddr() and I just want to ask the internet which method I should use. The point of this function is to get the IP address of a http.Request without the trailing port. E.g. 192.168.1.1 will instead of 192.168.1.1:6969.
Which method is the most idiomatic?
func getIPAddr(ip string) string {
return strings.Split(ip, ":")[0]
}
ip := getIPAddr(r.RemoteAddr)
OR
func getIPAddr(r *http.Request) string {
return strings.Split(r.RemoteAddr, ":")[0]
}
ip := getIPAddr(r)
**评论:**
nemith:
RalphCorderoy:One is much easier to write unit tests for.
You should also use https://golang.org/pkg/net/#SplitHostPort instead of writing your own. With IPv6 your function will fail.
seriouslulz:This isn't Go specific. Your first version has lower coupling and that is good. The function can be used by a caller that has an
ip string
, but no http.Request. Sure, they could build a temporary Request just to set RemoteAddr, but then they're increasing the coupling even more by relying on knowledge of how getIPAddr() works. https://en.wikipedia.org/wiki/Coupling_(computer_programming)
Saethgokk:First one. In general it's bad style to pass a struct when you only need to access one element, makes testing harder.
vorg:Use the first one and please also check is the string is empty or not
dilap:For this particular use case, don't just make the
.RemoteAddr
field explicit in the calling code, but also skip the function and use:ip := strings.Split(r.RemoteAddr, ":")[0]
The
":"
and[0]
are the only extra info and don't need hiding away in a function, just as.RemoteAddr
doesn't.
For a private helper function, either is fine IMO. The second form makes your calling code simpler, which can be a benefit.
Contrary some comments, I think they are equally easy to write unit tests for. (&http.Request{RemoteAddr: SOMETESTVALUE} isnt hard.)
For a public function I agree the function should take no more than it needs, i.e., prefer the former.
