ksimka / go-is-not-good

A curated list of articles complaining that go (golang) isn't good enough
3.82k stars 129 forks source link

We must be careful when we use interface{} #58

Closed YvesZHI closed 1 year ago

YvesZHI commented 4 years ago
func MyFunc(obj interface{}) {
    obj = "123"
    fmt.Println(obj)
}

func main() {
    var s string = "hello"
    MyFunc(s)
    fmt.Println(s)
    MyFunc(&s)
    fmt.Println(s)
}

The parameter of interface{} can be assigned by a normal type or by a pointer. That means:

  1. If we want to change the value by passing parameter, we must be careful while coding, because what we need is MyFunc(&s) but MyFunc(s) won't cause any error.
  2. If we do not want to change the value while passing parameter, we must be careful while coding, because what we need is MyFunc(s), but MyFunc(&s) won't cause any error.

This kind of "freedom" is not C-style freedom at all, let me explain:

void swap(int a, int b)  // Oops, this function can't swap a and b actually...
{
    int tmp = a;
    a = b;
    b = tmp;
}

A C beginner may code as above, that's because this beginner don't know C very well.

A Go expert may code MyFunc(s) but what he really needs is MyFunc(&s). This expert knows everything about Go, but he still can make such a mistake accidentally only because he is tired, or his girlfriend just called him etc...

Or let's imagine that MyFunc(interface{}) is a third-party library, there is no way to force the user of the library to call the method by MyFunc(&s), instead of MyFunc(s). But if this is a C library, if you try to call the function swap(a, b), you must get an error because this function is defined as swap(int *, int *). You don't need to be careful while coding C.

In a word, for C, we say you must learn a lot to avoid some mistakes. But for Go, we say you must be careful to avoid some mistakes.

This kind of "freedom" makes Go like a "stupid bady".