Go is Not Python
seanhelvey.com
seanhelvey.com
The title has to do with a common use case of Go, referred to in the opening example, where it is a common choice to move to from Python for speed.
> It's just pointing out a language gotcha/subtlety.
The implied motivation for posting this (see the closing line) is that the author has see this bite people coming to Go from Python.
Go won't hold your hands because it's more efficient if you are explicit. If you want a "reference" to the real original, your array needs to be an array of pointers.
It's pretty simple to understand when you have worked with pointers before and understand how the memory is allocated and eventually collected (and why you don't want to reallocate every loop iteration).
Finally, nil is the default value of anything with type (star)Student, and almost nobody uses arrays in Go ([2]Student is an array, []Student is a much-more-useful slice). In general, I don't think this author has written much Go code. It's probably a good idea to get a little more experience with whatever you're complaining about before writing a blog post about it, and likely misinforming your readers.
It's pretty straightforward code when you write what you explicitly want:
package main
import (
"fmt"
)
type Student struct {
name string
}
func main() {
students := []*Student{{"fred"}, {"karen"}}
var fredPtr *Student
for _, student := range students {
if student.name == "fred" {
fredPtr = student
}
}
fmt.Println(fredPtr.name)
}Although technically he was trying to get a pointer/reference to the student in the array, not a copy of its value
eg:
fredPtr = nil // This line is superfluous.
In Go, declarations always initialise variables to their zero value, which for all pointers is nil.(Perhaps worthy of a follow up article: "Go is Not C/C++"? ;)
func findByName(students []*Student, name string) *Student {
for _, s := range students {
if s.name == name {
return s
}
}
return nil
}
Both options have the added advantage of stopping iteration as soon as the result is found.Except the difference is not in similar syntax with different semantics; since it's the application of the & operator, which has no close parallel in Python, that is the source of the surprise.
Both languages have their strengths. When you pick a language for an application, it is your responsibility to use it properly. Otherwise you will make mistakes and it won't be the fault of the language.
Nothing in the article suggests not learning Go because of this behavior; the article is warning about a behavior developers coming to Go from Python are, in the author's experience, often bitten by, so that other people taking the same path can avoid making the same mistake.
> When you pick a language for an application, it is your responsibility to use it properly.
Yes, and this article aims to help people coming to Go from Python to do that by pointing out a common pitfall.
Python: How is `Fred` available to be printed in the Python example, is not it out of scope?
Go: Why use `var fredPtr *Student`? What's the point? Can not use `var fredPtr Student` and the set `fredPtr = student` in the loop?
— Go is basically a better (more evolved?) C.
I personally don't really care how easy it is to write a "hello world" in Go, nor Python. My day job involves big projects, so I'm pretty fine with "hello world" taking 10k lines as long as it will scale slower with complexity than other language. The same argument about learning curve -- I would be happy with a language that requires couple of years of learning to even start, as long as it takes less time in the following 20 years I'm going to be using it.
What gives you that impression?
Also, indent with two spaces to get code formatting. HN formatting is (sadly) not Markdown.