【问题标题】:What is the difference between print and puts?print 和 puts 有什么区别?
【发布时间】:2011-06-28 11:10:36
【问题描述】:

例如在我写的这行代码中,print 和 puts 产生不同的结果。

1.upto(1000).each { |i| print i if i % 2 == 0 }

【问题讨论】:

标签: ruby


【解决方案1】:

puts 如果还没有参数,则在每个参数的末尾添加一个新行。

print 不添加新行。


例如:

puts [[1,2,3], [4,5,nil]] 会返回:

1 2 3 4 5

而print [[1,2,3], [4,5,nil]] 会返回:

[[1,2,3], [4,5,nil]]
注意 puts 不输出 nil 值,而 print 输出。

【讨论】:

  • 实际上,每个参数后面都有一个换行符。这是一个关键点,在 Ruby 文档中并不清楚(因为该示例只有 1 个参数)。
  • 还有一件事......扩展数组类并覆盖to_s方法。 puts 不会将新的 to_s 用于新类的对象,而 print 会
  • 使用 irb 0.9.5 puts("a") 和 puts("a\n") 在 REPL 上的输出完全相同。
  • @kapv89 这不是真的:我刚刚尝试过,两者都将 e print 使用 to_s 方法。只有 p 不使用它。
  • @Fronker,这仍然只是一个论点。编译器连接相邻的字符串。
【解决方案2】:

一个很大的区别是你是否显示数组。 尤其是那些有 NIL 的。 例如:

print [nil, 1, 2]

给予

[nil, 1, 2]

但是

puts [nil, 1, 2]

给予

1
2

注意,没有出现 nil 项目(只是一个空行)并且每个项目都在不同的行上。

【讨论】:

  • 我今天注意到了这一点,它把我带到了这里。我很想知道对此的想法。 put 处理这样的数组似乎是一种特殊情况。想知道其基本原理是什么...只是为了类似于其他语言吗?
  • 这是有道理的,因为 puts 将输出一个新行,因此您可以将其视为在数组上迭代并在每一行上调用 puts ......然而,这很奇怪,它没有t 输出nil
【解决方案3】:

print 输出每个参数,然后是$,,到$stdout,然后是$\。相当于args.join($,) + $\

puts 将$, 和$\ 都设置为“\n”,然后执行与print 相同的操作。主要区别在于 每个参数 是带有 puts 的新行。

您可以通过require 'english' 使用user-friendly names 访问这些全局变量。

【讨论】:

  • english lib 的好技巧
【解决方案4】:

The API docs 给出一些好的提示:

print() → nil

print(obj, ...) → nil

将给定对象写入ios。返回nil。

必须打开流进行写入。每个给定的对象不是 字符串将通过调用其to_s 方法进行转换。什么时候 不带参数调用,打印 $_ 的内容。

如果输出字段分隔符($,)不是nil,它 插入对象之间。如果输出记录分隔符 ($\) 不是nil,它被附加到输出中。

...

puts(obj, ...) → nil

将给定对象写入ios。在任何之后写一个换行符 还没有以换行序列结束。返回nil。

必须打开流进行写入。如果使用数组参数调用, 将每个元素写入新行。每个给定的对象不是 字符串或数组将通过调用其to_s 方法进行转换。 如果不带参数调用,则输出一个换行符。

对上面给出的几点进行一些实验,差异似乎是:

  • 使用多个参数调用时,print 用“输出字段分隔符”$,(默认为空)将它们分开,而puts 用换行符将它们分开。 puts 还在最后一个参数后放置一个换行符,而 print 没有。

    2.1.3 :001 > print 'hello', 'world'
    helloworld => nil 
    2.1.3 :002 > puts 'hello', 'world'
    hello
    world
     => nil
    2.1.3 :003 > $, = 'fanodd'
     => "fanodd" 
    2.1.3 :004 > print 'hello', 'world'
    hellofanoddworld => nil 
    2.1.3 :005 > puts 'hello', 'world'
    hello
    world
     => nil
  • puts 自动解包数组,而print 不会:

    2.1.3 :001 > 打印 [1, [2, 3]], [4]
    [1, [2, 3]][4] => 无
    2.1.3 :002 > 放置 [1, [2, 3]], [4]
    1
    2
    3
    4
     => 无
  • print 不带参数打印$_(gets 读取的最后一件事),而puts 打印换行符:

    2.1.3 :001 > gets
    hello world
     => "hello world\n" 
    2.1.3 :002 > puts
    
     => nil 
    2.1.3 :003 > print
    hello world
     => nil
  • print 将输出记录分隔符 $\ 写在它打印的任何内容之后,而 puts 忽略此变量:

    mark@lunchbox:~$ irb
    2.1.3 :001 > $\ = 'MOOOOOOO!'
     => "MOOOOOOO!" 
    2.1.3 :002 > puts "Oink! Baa! Cluck! "
    Oink! Baa! Cluck! 
     => nil 
    2.1.3 :003 > print "Oink! Baa! Cluck! "
    Oink! Baa! Cluck! MOOOOOOO! => nil

【讨论】:

    【解决方案5】:

    puts 调用每个参数的to_s 并为每个字符串添加一个新行,如果它不以新行结尾。 print 只需通过调用 to_s 来输出每个参数。

    例如: puts "one two": one two

    {换行}

    puts "one two\n": one two

    {new line} #puts 不会在结果中添加新行,因为字符串以新行结尾

    print "one two": one two

    print "one two\n": one two

    {换行}

    还有另一种输出方式:p

    对于每个对象,直接将 obj.inspect 后跟换行符写入程序的标准输出。

    输出调试信息很有帮助。 p "aa\n\t":aa\n\t

    【讨论】:

      【解决方案6】:

      如果您想使用puts 在字符串中输出数组,您将获得与使用print 相同的结果:

      puts "#{[0, 1, nil]}":
      [0, 1, nil]
      

      但如果没有带引号的字符串,那么是的。唯一的区别是我们使用puts时的新行。

      【讨论】:

      • -1 有两个原因。首先,缺乏明确性:我不明白这里最初的“但是......”打算从什么开始,我也不明白最后一段中的“是”在回答什么。其次,由于缺乏正确性:您说在示例代码中使用 printf 而不是 puts 会产生相同的结果,但实际上并非如此。 puts 变体在末尾添加换行符,而printf 没有,就像没有插入到字符串中的数组的情况一样。 (必然如此,因为在评估字符串文字时会发生插值。)
      • 啊哈!阅读其他答案后,我想我明白了-您打算这是对stackoverflow.com/a/14534145/1709587的回复吗?无论如何,它本身并没有真正的答案。
      猜你喜欢
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      • 2011-01-28
      • 2016-03-03
      • 2010-10-11
      • 2013-11-14
      • 2010-12-11
      • 1970-01-01
      相关资源
      最近更新 更多