fmt.Scanner 出现意外的 EOF
unexpected EOF with fmt.Scanner
如果我想扫描一个字符串,我可以这样做:
package main
import (
"fmt"
"strings"
)
func main() {
r := strings.NewReader("west north east")
for {
var s string
_, e := fmt.Fscan(r, &s)
fmt.Printf("%q %v\n", s, e)
if e != nil { break }
}
}
结果:
"west" <nil>
"north" <nil>
"east" <nil>
"" EOF
我最近发现了 fmt.Scanner
[1],所以我想我会尝试实现
它。我想到了这个:
package main
import (
"fmt"
"strings"
)
type comma struct { tok string }
func (c *comma) Scan(state fmt.ScanState, verb rune) error {
tok, err := state.Token(false, func(r rune) bool {
return r != ','
})
if err != nil {
return err
}
if _, _, err := state.ReadRune(); err != nil {
if len(tok) == 0 {
return err
}
}
c.tok = string(tok)
return nil
}
func main() {
r := strings.NewReader("west,north,east")
for {
var c comma
_, e := fmt.Fscan(r, &c)
fmt.Printf("%q %v\n", c.tok, e)
if e != nil { break }
}
}
结果:
"west" <nil>
"north" <nil>
"east" <nil>
"" unexpected EOF
所以结果非常接近,但令我困扰的是 unexpected EOF
。是
有可能只得到一个普通的 EOF
和一个自定义的 fmt.Scanner
吗?我在做什么
这里有问题,或者这是一个错误?
感谢 golang-nuts
名单上的 Ian Lance Taylor,他建议 panic
错误而不是 return
。在 Go 代码中,Fscan
调用了一个函数
doScan
,它又调用了一个函数errorHandler
[1]。最后一个功能
使用 recover
将任何 panic
转换为常规错误。这个程序给
与我的原始示例相同的输出:
package main
import (
"fmt"
"strings"
)
type comma struct { tok string }
func (c *comma) Scan(state fmt.ScanState, verb rune) error {
tok, err := state.Token(false, func(r rune) bool {
return r != ','
})
if err != nil { return err }
if _, _, err := state.ReadRune(); err != nil {
if len(tok) == 0 {
panic(err)
}
}
c.tok = string(tok)
return nil
}
func main() {
r := strings.NewReader("west,north,east")
for {
var c comma
_, err := fmt.Fscan(r, &c)
fmt.Printf("%q %v\n", c.tok, err)
if err != nil { break }
}
}
如果我想扫描一个字符串,我可以这样做:
package main
import (
"fmt"
"strings"
)
func main() {
r := strings.NewReader("west north east")
for {
var s string
_, e := fmt.Fscan(r, &s)
fmt.Printf("%q %v\n", s, e)
if e != nil { break }
}
}
结果:
"west" <nil>
"north" <nil>
"east" <nil>
"" EOF
我最近发现了 fmt.Scanner
[1],所以我想我会尝试实现
它。我想到了这个:
package main
import (
"fmt"
"strings"
)
type comma struct { tok string }
func (c *comma) Scan(state fmt.ScanState, verb rune) error {
tok, err := state.Token(false, func(r rune) bool {
return r != ','
})
if err != nil {
return err
}
if _, _, err := state.ReadRune(); err != nil {
if len(tok) == 0 {
return err
}
}
c.tok = string(tok)
return nil
}
func main() {
r := strings.NewReader("west,north,east")
for {
var c comma
_, e := fmt.Fscan(r, &c)
fmt.Printf("%q %v\n", c.tok, e)
if e != nil { break }
}
}
结果:
"west" <nil>
"north" <nil>
"east" <nil>
"" unexpected EOF
所以结果非常接近,但令我困扰的是 unexpected EOF
。是
有可能只得到一个普通的 EOF
和一个自定义的 fmt.Scanner
吗?我在做什么
这里有问题,或者这是一个错误?
感谢 golang-nuts
名单上的 Ian Lance Taylor,他建议 panic
错误而不是 return
。在 Go 代码中,Fscan
调用了一个函数
doScan
,它又调用了一个函数errorHandler
[1]。最后一个功能
使用 recover
将任何 panic
转换为常规错误。这个程序给
与我的原始示例相同的输出:
package main
import (
"fmt"
"strings"
)
type comma struct { tok string }
func (c *comma) Scan(state fmt.ScanState, verb rune) error {
tok, err := state.Token(false, func(r rune) bool {
return r != ','
})
if err != nil { return err }
if _, _, err := state.ReadRune(); err != nil {
if len(tok) == 0 {
panic(err)
}
}
c.tok = string(tok)
return nil
}
func main() {
r := strings.NewReader("west,north,east")
for {
var c comma
_, err := fmt.Fscan(r, &c)
fmt.Printf("%q %v\n", c.tok, err)
if err != nil { break }
}
}