与 String 相比,在 Ruby 中使用 StringIO 有啥优势?

Posted

技术标签:

【中文标题】与 String 相比,在 Ruby 中使用 StringIO 有啥优势?【英文标题】:What are the advantages to using StringIO in Ruby as opposed to String?与 String 相比,在 Ruby 中使用 StringIO 有什么优势? 【发布时间】:2012-09-17 12:26:41 【问题描述】:

什么时候使用 Ruby 的 StringIO 而不是只使用 String 才是合适的?

我想我理解它们之间的根本区别,正如“What is ruby's StringIO class really?”所强调的那样,StringIO 使人们能够以面向流的方式读取/写入字符串。但这实际上意味着什么?

当简单地使用 String 并不能真正削减它时,使用 StringIO 的实际用途的一个很好的例子是什么?

【问题讨论】:

【参考方案1】:

基本上,它使字符串看起来像一个 IO 对象,因此命名为 StringIO。

StringIO 类具有 readwrite 方法,因此可以将其传递给设计用于从文件或套接字读取和写入的代码部分。如果你有一个字符串并且你希望它看起来像一个文件来测试你的文件代码,那就太好了。

def foo_writer(file)
  file.write "foo"
end

def test_foo_writer
  s = StringIO.new
  foo_writer(s)
  raise "fail" unless s.string == "foo"
end

【讨论】:

有趣。与 String 相比,使用 StringIO 是否有任何优势(关于内存使用)? 可能不会。如果您查看源代码,它看起来只是在内部保留了对 String 对象的引用,因此它会比普通字符串使用稍多的内存:github.com/ruby/ruby/blob/trunk/ext/stringio/stringio.c 虽然如果您使用StringIO 并没有内存优势,但如果您为 IO 对象设计函数,您可以执行诸如从文件读取之类的操作,或者一起进行管道操作。因此,如果与适当的类一起使用,则采用 IO 对象的函数可以使用更少的内存。因此,这使您可以以相同的方式对 String 或可能更高效的 IO 对象进行操作。 请记住,StringIOFile 的外观完全相同。我刚刚遇到的一个“问题”——File.size(StringIO.new('foo')) #=> TypeError: no implicit conversion of StringIO into String【参考方案2】:

我真的很喜欢 StringIO 用于逐行附加文本的用例,而不必一遍又一遍地使用"\n"。例如,而不是这个:

s = ''
s << "\n" << "some text on a new line"
s << "\nthis is pretty awkward"
s = "#s\neven more ugly!"

我能做到

s = StringIO.open do |s|
  s.puts 'adding newlines with puts is easy...'
  s.puts 'and simple'
  s.string
end

这更清洁。不必使用String.IO 的块形式,您可以像这样创建一个对象:s = StringIO.new 但无论如何,请务必记住实际字符串是通过StringIO#string 方法访问的。

【讨论】:

我通常使用Array#&lt;&lt; 然后Array#join 来处理这种事情,尽管使用StringIO 是一种很棒的技术。 @jc00ke 我也是。现在我对 Ruby 更加熟悉了,我的习惯导致代码有利于读者...为了说明我的意思,请考虑以下内容:对于编码人员,使用 Array 就像你描述的那样当然,写入很方便,但是当读取代码时,类名StringIO是一个更好的目的指标。更不用说Array 是一个根本不同的数据结构。此外,使用Array#join 的必要性会导致过多的代码“包袱”,更糟糕的是,复杂性!例如,它的参数默认设置为全局变量。 我喜欢这个,我在偷它。现在。

以上是关于与 String 相比,在 Ruby 中使用 StringIO 有啥优势?的主要内容,如果未能解决你的问题,请参考以下文章

提高篇:RMQ问题与ST表

为啥使用 st_intersection 而不是 st_intersects?

怎样把一个String类型的时间与当前时间相比

如何使用 render_to_string 在 lib ruby​​ 类中渲染部分内容

与 xgboost.cv 相比,GridSearchCV 没有给出与预期相同的结果

@,x,X 指令如何与 Ruby pack()/unpack() 方法一起使用?