Exercise: Readers
实现发出ASCII字符“A”的无限流的Reader类型。
我不明白这个问题,如何发出字符'A'?我应该把这个字符设置到哪个变量中?
以下是我的尝试:
package main
import "golang.org/x/tour/reader"
type MyReader struct{}
// TODO: Add a Read([]byte) (int, error) method to MyReader.
func main() {
reader.Validate(MyReader{}) // what did this function expect?
}
func (m MyReader) Read(b []byte) (i int, e error) {
b = append(b, 'A') // this is wrong..
return 1, nil // this is also wrong..
}
6条答案
按热度按时间eiee3dmh1#
啊我明白XD
我想最好还是说:“将
[]byte
中的所有值重写为'A'
s”68de4m5k2#
io.Reader.Read
的作用是将从源读取的数据写入给定的存储器位置。要实现
'A'
的流,函数必须使用'A'
值写入给定的内存位置。它不需要填充input中提供的整个切片,它可以决定写入输入切片的多少字节(
Read reads up to len(p) bytes into p
),它必须返回该数字以向使用者指示要处理的数据长度。按照惯例,
io.Reader
通过返回一个io.EOF
错误来指示它的结束。如果读取器没有返回错误,它就像是一个无限的数据源,它的使用者永远无法检测到退出条件。请注意,对
Read
的调用可能会返回0 bytes
read,但这并不表示任何特殊情况,Callers should treat a return of 0 and nil as indicating that nothing happened;
Which makes this non-solution https://play.golang.org/p/aiUyc4UDYi2会因超时而失败。考虑到这一点,这里提供的解决方案https://stackoverflow.com/a/68077578/4466350
return copy(b, "A"), nil
非常合适,它编写了所需的最小值,巧妙地使用了内置函数和语法工具,而且从不返回错误。bybem2ql3#
所谓的答案是对我不起作用,即使没有错别字,我也试过,那个字符串不会进入B。
x7rlezfr4#
我的解决方案:每次只添加一个字节,使用闭包存储索引
i
。o3imoua45#
最简单的一个:
91zkwejq6#
你可以把这个想法推广到创建一个永恒的读取器
alwaysReader
,从这个读取器你总是一遍又一遍地读取相同的字节值(它永远不会导致EOF):NewAlwaysReader()
是alwaysReader
的构造函数(未导出),NewAlwaysReader('A')
的结果是一个读取器,您将始终从该读取器读取'A'
。alwaysReader
的澄清单元测试:因为我们可以永远从
alwaysReader
读取数据,所以我们需要用一个io.LimitReader
来修饰它,这样我们最多可以从它阅读numBytes
,否则,bytes.Buffer
最终会因为io.Copy()
而耗尽内存来重新分配它的内部缓冲区。请注意,
Read()
的以下实现对于alwaysReader
也是有效的:前一个
Read()
实现用字节值填充整个字节片,而后一个实现只写入单个字节。