【问题标题】:how to pass strings to functions not by ref (Ruby)如何将字符串传递给函数而不是 ref (Ruby)
【发布时间】:2011-08-22 13:25:52
【问题描述】:

检查以下代码

def wipe_mutterings_from( sentence )
   while sentence.include? '('
     open = sentence.index( '(' )
     close = sentence.index( ')', open )
     sentence[open..close] = '' if close
   end
end

foo='abbba (jjjj) kkkkkk'
wipe_mutterings_from( foo )
p foo

据我了解,我已通过 ref 将字符串传递给函数(很像在 c/cpp 等低级语言中所做的)。
是否可以仅按值传递字符串(如在 PHP 中)?
我完全知道我可以在函数内复制字符串并仅在副本上工作。

【问题讨论】:

    标签: ruby string pass-by-reference pass-by-value


    【解决方案1】:

    不,在 Ruby 中一切都是通过引用传递的,字符串是可变的。常见的做法是dup 字符串是方法中的第一件事,正如您所提到的。

    然而,一个更简单的方法是不做sentence[open..close],而是像sentence[0...open] + sentence[(close + 1)..-1] 这样为每次迭代创建一个新字符串。这样你就不必担心改变字符串。另一方面,该解决方案会创建更多的字符串对象,这会降低性能,因为垃圾收集器必须做更多的工作,但这只有在你这样做数万次时才有意义。

    【讨论】:

    • 不,在 Ruby 中一切都是按值传递的,而那些值是引用;就像 Java 中的对象一样
    【解决方案2】:

    或者您可以尝试一种更“红宝石”的方式(消除 while 循环和索引计算):

    foo = 'abbba (jjjj) kkkkkk'
    p foo.sub(/\(.*\) /, '')
    

    【讨论】:

    • 我问题中的代码来自教程,虽然您的回答对我提供的功能解决的特定问题有好处,但这不是我问题的主题。但是,谢谢!
    【解决方案3】:

    您可以尝试仅发送此字符串的副本

    foo='abbba (jjjj) kkkkkk'
    wipe_mutterings_from( foo.clone )
    p foo
    

    【讨论】:

      【解决方案4】:

      我看不出您为什么不在函数中创建新字符串并将其返回的任何原因。它读起来更好,而且惊喜更少:

      foo='abbba (jjjj) kkkkkk'
      new_foo = wipe_mutterings_from( foo )
      p new_foo
      

      甚至

      foo='abbba (jjjj) kkkkkk'
      foo = wipe_mutterings_from( foo )
      p foo
      

      不过,我更喜欢后者。

      【讨论】:

      • 我不是在寻找一个理由,只是如果它在 Ruby 中是可能的,我正在学习这门语言......
      猜你喜欢
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 2018-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      相关资源
      最近更新 更多