editor php Strawberry akan memperkenalkan kepada anda masalah gelung tak terhingga io.Reader dan fmt.Fscan dalam artikel ini. Apabila menggunakan fungsi fmt.Fscan untuk membaca input, jika kandungan yang dibaca tidak sepadan dengan format input, gelung tak terhingga akan berlaku. Masalah ini mungkin menyebabkan kita banyak masalah, tetapi dengan beberapa petua dan langkah berjaga-jaga, kita boleh menyelesaikan masalah ini dengan mudah. Seterusnya, kami akan menerangkan secara terperinci cara mengelakkan gelung tak terhingga dalam io.Reader dan fmt.Fscan untuk membantu anda menggunakan kedua-dua fungsi ini dengan lebih baik.
Tidak tahu mengapa, tetapi pelaksanaan io.reader
saya nampaknya mempunyai sedikit kecacatan?
io.reader
menyatakan bahawa mengembalikan kiraan bait bukan sifar dan ralat bukan sifar sepatutnya baik:
it may return the (non-nil) error from the same call or return the error (and n == 0) from a subsequent call. an instance of this general case is that a reader returning a non-zero number of bytes at the end of the input stream may return either err == eof or err == nil. the next read should return 0, eof. callers should always process the n > 0 bytes returned before considering the error err. doing so correctly handles i/o errors that happen after reading some bytes and also both of the allowed eof behaviors.
Tetapi ini tidak berfungsi untuk fmt.fscan
dan sebaliknya menggantung program:
package main import ( "fmt" "io" ) type byte byte func (b byte) read(p []byte) (n int, err error) { if len(p) == 0 { return 0, io.errshortbuffer } p[0] = byte(b) return 1, io.eof } func main() { var n int b := byte('9') z, err := fmt.fscan(b, &n) fmt.println(n, z, err) }
Sudah tentu, jika saya menggunakan io.eof
sahaja ia mengembalikan kiraan bait sifar:
type Byte struct { v byte eof bool } func (b *Byte) Read(p []byte) (n int, err error) { if len(p) == 0 { return 0, io.ErrShortBuffer } if b.eof { return 0, io.EOF } p[0] = b.v b.eof = true return 1, nil } func main() { var n int b := Byte{v: '9'} z, err := fmt.Fscan(&b, &n) fmt.Println(n, z, err) }
Adakah terdapat kecacatan dalam pelaksanaan asal saya atau saya tidak patut bergantung pada gelagat pengelogan khusus ini io.reader
的这一特定记录行为,并且在没有更多数据可供读取时始终单独返回 0, io.eof
?
fmt.scanf
确实正确处理返回计数和 io.eof
,但即使在 io.eof
dan sentiasa mengembalikan 0, io.eof
sahaja apabila tiada lagi data untuk dibaca ?
io.readfull
,而后者使用 io.readatleast
,因此您将需要一个更完整的实现来处理重复读取。您可以通过使用跟踪 eof 的扩展版本来测试这一点,并在第一个 read
上返回 io.eof
,它仍然可以按预期与 fmt.fscan
fmt.scanf
mengendalikan kiraan pulangan dan
.
Memandangkan pelaksanaan pengimbas bergantung pada penggunaan io.readfull
yang menggunakan
pada baca
pertama dan ia masih akan berfungsi dengan
io.readatleast
Petikan utama daripada dokumentasi:
io
帮助程序需要自己解释 io.eof
,所以它们的调用者只能查找返回的实际数据,并且由于您的阅读器继续返回数据,它们将无限期地重复调用。通过在阅读器上重复调用 io.readall
...ia tidak menganggap eof dalam dibaca sebagai ralat untuk melaporkan
io
ini perlu mentafsir 🎜 sendiri, pemanggil mereka hanya boleh mencari data sebenar yang dikembalikan dan memandangkan pembaca anda terus memulangkan data, mereka akan dipanggil berulang kali selama-lamanya. Ini boleh ditunjukkan dengan mudah dengan memanggil io.readall
berulang kali pada pembaca, mengembalikan nilai lain setiap kali. 🎜
b := Byte('9') fmt.Println(io.ReadAll(b)) fmt.Println(io.ReadAll(b)) fmt.Println(io.ReadAll(b)) // [57] <nil> // [57] <nil> // [57] <nil>
Atas ialah kandungan terperinci io.Reader dan fmt.Fscan gelung tak terhingga. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!