-
-
Save bmizerany/fcd0348bda96edce05a4fc7426e47751 to your computer and use it in GitHub Desktop.
| package question | |
| func whatsTheEquivalentOfThisWithHandleCheckQuestionMark(w io.Writer) (rN int, err error) { | |
| w = LimitedWriter{w, 23} | |
| n, err := io.WriteString(w, "some data 1") // 11 bytes written | |
| rN += n | |
| if err != nil { | |
| return err | |
| } | |
| n, err := io.WriteString(w, "some data 2") // 22 bytes written | |
| rN += n | |
| if err != nil { | |
| return err | |
| } | |
| n, err := io.WriteString(w, "some data 3") // 23 bytes written: BOOM!!! | |
| rN += n | |
| return rN, err | |
| } | |
| func canItBeThisQuestionMark(w io.Writer) (n int, err error) { | |
| handle err { return n, err } | |
| w = LimitedWriter{w, 23} | |
| n += check io.WriteString(w, "some data 1") // 11 bytes written | |
| n += check io.WriteString(w, "some data 2") // 22 bytes written | |
| n += check io.WriteString(w, "some data 3") // 23 bytes written: BOOM!!! | |
| return nil | |
| } |
I do not see a problem.
With handle err { return n, err }, it will return 22, err
With handle err { return n, err }, it will return 0, err
Programmer is in control. Sometimes it might be exactly what you want. I.e. what if you are consuming data from a socket or pipe, or parsing, and you find an error only at position x. Similarly if the WriteString is to a socket. You can't unread / unwrite this data.
If you are asking about whatever n will be updated, in a situation where WriteString returns (1, SomeError), then this 1 will be ignored, and n += 1, will not be performed.
In a situation like this you would write:
n3, err = io.WriteString(w, "some data 3")
n += n3
check errmaybe?
This is because n += check X()
is rewritten to:
``
temp, err := X()
if err != nil { call handler with err; return; }
n += temp
This is the same as using normal `:=` operator:
``
temp, err := X()
if err != nil { call handler with err; return; }
n := temp
Notice that in Go you can't express assignment to err, and increment of n in a single statement anyway.
It does mean however than
n = check X()and
n, err = X()
if err != nil { return err; }do have different semantic (and the first one would use extra register / stack space). This probably only applies to return values tho. In other cases, compiler should be able to do the same as before.
I did not see the semantic explained precisely in current drafts tho.
@elimisteve your version returns n = 22, not 23, right?