Consider the following program: https://play.golang.org/p/_RjR5dCQ_KW
package main
import (
"bufio"
"strings"
"fmt"
)
const data = "short\nthisisverylonglong\n"
var in = bufio.NewScanner(strings.NewReader(data))
func next() []byte {
in.Scan()
return in.Bytes()
}
func main() {
in.Buffer(make([]byte, 20), 20)
s, t := string(next()), next() // line 20
fmt.Println(s)
fmt.Printf("%s\n", t)
}
What I expected at line 20:
1) call next()
2) convert it to string
3) call next()
4) assign to s and t
Expected output:
short
thisisverylonglong
What was the actual compiled code:
1) call next()
2) call next()
3) convert first result to string
4) assign to s and t
Actual output:
thisi
thisisverylonglong
0x008f 00143 (longscan.go:20) PCDATA $0, $0
0x008f 00143 (longscan.go:20) CALL "".next(SB)
0x0094 00148 (longscan.go:20) MOVQ 8(SP), AX
0x0099 00153 (longscan.go:20) MOVQ AX, ""..autotmp_21+88(SP)
0x009e 00158 (longscan.go:20) MOVQ 16(SP), CX
0x00a3 00163 (longscan.go:20) MOVQ CX, ""..autotmp_22+80(SP)
0x00a8 00168 (longscan.go:20) MOVQ (SP), DX
0x00ac 00172 (longscan.go:20) MOVQ DX, ""..autotmp_23+104(SP)
0x00b1 00177 (longscan.go:20) PCDATA $0, $1
0x00b1 00177 (longscan.go:20) CALL "".next(SB)
0x00b6 00182 (longscan.go:20) MOVQ 16(SP), AX
0x00bb 00187 (longscan.go:20) MOVQ AX, "".t.cap+72(SP)
0x00c0 00192 (longscan.go:20) MOVQ 8(SP), CX
0x00c5 00197 (longscan.go:20) MOVQ CX, "".t.len+64(SP)
0x00ca 00202 (longscan.go:20) MOVQ (SP), DX
0x00ce 00206 (longscan.go:20) MOVQ DX, "".t.ptr+96(SP)
0x00d3 00211 (longscan.go:20) MOVQ $0, (SP)
0x00db 00219 (longscan.go:20) MOVQ ""..autotmp_23+104(SP), BX
0x00e0 00224 (longscan.go:20) MOVQ BX, 8(SP)
0x00e5 00229 (longscan.go:20) MOVQ ""..autotmp_21+88(SP), BX
0x00ea 00234 (longscan.go:20) MOVQ BX, 16(SP)
0x00ef 00239 (longscan.go:20) MOVQ ""..autotmp_22+80(SP), BX
0x00f4 00244 (longscan.go:20) MOVQ BX, 24(SP)
0x00f9 00249 (longscan.go:20) PCDATA $0, $2
0x00f9 00249 (longscan.go:20) CALL runtime.slicebytetostring(SB)
0x00fe 00254 (longscan.go:20) MOVQ 32(SP), AX
0x0103 00259 (longscan.go:20) MOVQ 40(SP), CX
In this case, second next() causes Scanner buffer clear, which invalidates
result of first next() before making it to string.
I think https://golang.org/ref/spec#Order_of_evaluation is going to explain
this situation, but I had hard time understanding.
Is current behavior consistent with language spec?
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.