Why using naked return and the normal return give me different results?

770 views Asked by At

I'm playing around with Golang tour and I wonder why using naked return give me the correct result but the normal one doesn't. This is the exercise that I have this problem https://tour.golang.org/methods/12.

The objective is to create a reader that can decipher rot13. and the rot13 function is already tested.

func (r rot13Reader) Read(b []byte) (n int, err error) {
    n, err =  r.r.Read(b)
    for i, v := range b {
        b[i] = rot13(v)
    }
    return
}

The code above give me the correct result.

func (r rot13Reader) Read(b []byte) (int, error) {
    for i, v := range b {
    b[i] = rot13(v)
    }
    return r.r.Read(b)
}

And this doesn't change anything from the input stream.

Could anybody explain why? Thank you in advance.

2

There are 2 answers

7
tomasz On BEST ANSWER

It's not a problem with returns, but in the first case you're reading the data in before transforming it and in the second case you're transforming junk in a buffer and only then reading in the data (and simply passing what has been read from the underlying reader).

While this is not required for correctness, I'd suggest you don't transform the whole buffer every time, but only the portion that has been read, i.e. changing your first example from for i, v := range b to for i, v := range b[:n]. That's because io.Read call is not able to modify length of slice b, but just its content.

Take a look at the documentation of io.Reader, it should give you some more idea on how this interface is expected to work.

0
ReyCharles On

The Read() operation mutates the input array b. In the second example the rot13() operations are overwritten by the Read() operation. Furthermore, the rot13() operation is performed before any data has been read into the array, so you're probably doing rot13() on garbage data.

If you wanted the second example to work you'd need to write something like this:

func (r rot13Reader) Read(b []byte) (int, error) {
    n, err := r.r.Read(b)
    for i, v := range b {
    b[i] = rot13(v)
    }
    return n, err 
}