为什么Ruby没有真正的StringBuffer或者StringIO?
时间:2020-03-05 18:39:29 来源:igfitidea点击:
我最近读了一篇关于在Ruby中使用StringIO
的不错的文章。不过,作者没有提及的是StringIO只是一个" I"。没有" O"。我们不能这样做,例如:
s = StringIO.new s << 'foo' s << 'bar' s.to_s # => should be "foo\nbar" # => really is ''`
就像Java一样,Ruby确实需要一个StringBuffer。 StringBuffers有两个重要目的。首先,他们让我们测试Ruby的StringIO所做的一半输出。其次,它们对于从细小的零件上串起长弦很有用-乔尔一遍又一遍地提醒我们,否则这将非常慢。
有没有好的替代品?
确实,Ruby中的字符串是可变的,但这并不意味着我们应该始终依赖该功能。如果stuff
很大,例如,它的性能和内存要求就很糟糕。
result = stuff.map(&:to_s).join(' ')
在Java中执行此操作的"正确"方法是:
result = StringBuffer.new("") for(String s : stuff) { result.append(s); }
虽然我的Java有点生锈。
解决方案
回答
好吧,StringBuffer在Ruby中并不是必需的,主要是因为Ruby中的字符串是可变的...因此,我们可以通过修改现有字符串来构建字符串,而不是使用每个concat构造新的字符串。
需要注意的是,我们还可以使用特殊的字符串语法,在其中我们可以构建一个引用该字符串中其他变量的字符串,从而使字符串的构造非常容易理解。考虑:
first = "Mike" last = "Stone" name = "#{first} #{last}"
这些字符串还可以包含表达式,而不仅仅是变量……例如:
str = "The count will be: #{count + 1}" count = count + 1
回答
我查看了StringIO
的ruby文档,看起来我们想要的是StringIO#string
,而不是StringIO#to_s
。
因此,将代码更改为:
s = StringIO.new s << 'foo' s << 'bar' s.string
回答
示例在Ruby中有效,我刚刚尝试过。
irb(main):001:0> require 'stringio' => true irb(main):002:0> s = StringIO.new => #<StringIO:0x2ced9a0> irb(main):003:0> s << 'foo' => #<StringIO:0x2ced9a0> irb(main):004:0> s << 'bar' => #<StringIO:0x2ced9a0> irb(main):005:0> s.string => "foobar"
除非我错过我们使用仅输出对象ID的to_s的原因,否则。
回答
与Ruby中的其他IO类型对象一样,当我们写入IO时,字符指针也会前进。
>> s = StringIO.new => #<StringIO:0x3659d4> >> s << 'foo' => #<StringIO:0x3659d4> >> s << 'bar' => #<StringIO:0x3659d4> >> s.pos => 6 >> s.rewind => 0 >> s.read => "foobar"
换皮这只猫的另一种方法。