【问题标题】:Why does io.WriterTo's WriteTo method return an int64 rather than an int?为什么 io.WriterTo 的 WriteTo 方法返回的是 int64 而不是 int?
【发布时间】:2015-06-21 22:12:37
【问题描述】:

Go's io package 中的大部分输出方法都返回(int, error),例如io.WriterWrite([]byte) 方法和io.WriteString(io.Writer, string) 函数。但是,一些输出方法,例如io.WriterToWriteTo 方法,会返回(int64, error)。这使得在不存储中间值并将其从int 类型转换为int64 的情况下以WriteWriteString 实现WriteTo 很不方便。造成这种差异的原因是什么?

【问题讨论】:

  • 非常有趣的问题。

标签: go io output standard-library


【解决方案1】:

WriteTo 复制的数据可能超过 int32 字节。

使用io.Readerio.Writer 接口,数据量受给定切片大小的限制,对于当前架构而言,该切片的长度受int 的限制。

【讨论】:

  • 我可能完全同意,但有趣的是,在语言规范中,int 可能是 32 位或 64 位,具体取决于实现/架构。在不查看使用WriterToWriter 接口的其他包的情况下,我的猜测是作者可能已经直觉到WriterTo/ReaderFrom 接口有更大的潜力来处理大量数据。跨度>
  • @JerrySaravia:这就是重点,WriterTo 和 ReaderFrom 可以处理大量数据。它们不限于使用单个切片进行操作。没什么好猜的。
  • 这是一个很好的观点。我猜WriterTo 可能正在复制大于 2GB 的文件或类似的文件。但是,为什么不在各处使用int64 以保持一致性呢?
  • @Matt: 因为它一致地在任何适当的数据类型处返回int,而不是在较少的情况下将所有内容都转换为int64在某些系统上可能。 Read 和 Write 中的值以切片的长度表示,通常用于对切片进行索引。换一种方式会有更多的转化。
  • @JimB 切片的大小是否有限制?我认为他们唯一的限制是可用内存的大小。
【解决方案2】:

Writer.Write() 方法的签名:

Write(p []byte) (n int, err error)

它写入 slice 的内容。引用自spec: Slice types

切片是底层数组的连续段的描述符...

众所周知,切片有一个底层数组。再次引用Spec: Array types

长度是数组类型的一部分;它必须计算为一个非负常数,该常数可由int 类型的值表示。

因此,数组的最大长度受int 类型的最大值的限制(32 位架构为2147483647,64 位架构为9223372036854775807)。

回到Writer.Write() 方法:因为它写入了传递的切片的内容,所以保证写入的字节数不会多于适合int 的内容。

现在WriteTo.WriteTo()方法:

WriteTo(w Writer) (n int64, err error)

没有提到切片或数组。您无法保证结果将适合 int,因此 int64 是完全合理的。

示例:BigBuffer

想象一个BigBuffer 实现,它临时将数据写入数组或切片。该实现可以管理多个数组,以便如果一个已满(例如达到最大 int),则继续另一个。现在如果这个BigBuffer实现了WriteTo接口,你调用这个方法将内容写入os.File,结果将超过最大int

【讨论】:

  • 一个更简单的例子是任何实现 WriteTo 的随机类型,用于可能具有 >31 位表示的事物(例如,表示/保存 2.01 GB 视频的类型;或愚蠢的 type Zeros int64被定义为写出那么多零的类型)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
  • 2020-04-16
  • 1970-01-01
  • 2022-07-22
  • 1970-01-01
  • 2015-01-02
相关资源
最近更新 更多