与 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 类具有 read
和 write
方法,因此可以将其传递给设计用于从文件或套接字读取和写入的代码部分。如果你有一个字符串并且你希望它看起来像一个文件来测试你的文件代码,那就太好了。
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 对象进行操作。
请记住,StringIO
与File
的外观完全相同。我刚刚遇到的一个“问题”——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#<<
然后Array#join
来处理这种事情,尽管使用StringIO
是一种很棒的技术。
@jc00ke 我也是。现在我对 Ruby 更加熟悉了,我的习惯导致代码有利于读者...为了说明我的意思,请考虑以下内容:对于编码人员,使用 Array
就像你描述的那样当然,写入很方便,但是当读取代码时,类名StringIO
是一个远更好的目的指标。更不用说Array
是一个根本不同的数据结构。此外,使用Array#join
的必要性会导致过多的代码“包袱”,更糟糕的是,复杂性!例如,它的参数默认设置为全局变量。
我喜欢这个,我在偷它。现在。以上是关于与 String 相比,在 Ruby 中使用 StringIO 有啥优势?的主要内容,如果未能解决你的问题,请参考以下文章
为啥使用 st_intersection 而不是 st_intersects?
如何使用 render_to_string 在 lib ruby 类中渲染部分内容