【问题标题】:Why doesn't print output anything on each iteration of a loop when I use sleep?当我使用睡眠时,为什么在循环的每次迭代中不打印输出任何内容?
【发布时间】:2011-07-02 17:52:10
【问题描述】:

今天在我的大学里,一位老师问了我一个问题。他在纸上写了这段代码并说 “这段代码的输出是什么?”

use warnings;

for (1 .. 20)
{
    print ".";
}

我发现这很简单,我说它会循环 20 次,每次迭代都会打印一个点 (.),因此总共会输出 20 个点。

他说你是对的,然后他对代码进行了一些更改。代码是:

use warnings;

for (1 .. 20)
{
    print ".";
    sleep 1;
}

他说现在的输出是什么?我不知道 sleep 函数,我猜在每次迭代时它都会打印点 (.) 然后它会等待 1 秒(因为 sleep 函数)然后它会再次迭代然后它会再次print (.) 然后它会等待 1 秒,依此类推...

老师让我在家检查。我在家里试过了,我知道第二个代码会等待 20 秒,然后它会一次打印所有点(20 个点)。我想知道这是怎么发生的?为什么每次迭代都没有打印点 (.)?

【问题讨论】:

    标签: perl buffering


    【解决方案1】:

    真正的问题与sleep无关,而是…………

    你是Suffering from Buffering。提供的链接将您带到 Marc Jason Dominus(Higher-Order Perl 的作者)大约 1998 年的 Perl Journal 中的一篇优秀文章。这篇文章可能已经有十多年的历史了,但这个话题在今天和他写这篇文章时一样重要。

    其他人已经解释了$| = 1; 技术。我要补充一点,在 Perl 社区的主要思想中,$| = 1$|++ 更可取,因为它的含义更清晰。我知道,自动增量也很简单,但是每个会查看您的代码的人都知道$| 在应用++-- 时的行为(无需在perlvar 中查找)。我碰巧也更喜欢本地化对 Perl 的“特殊变量”的任何修改,这样效果就不会影响到代码的其他部分,这些部分可能不会对默认 Perl 行为的特定更改起到很好的作用。既然如此,我会写成:

    use strict;
    use warnings;
    
    {
        local $| = 1;
        for ( 1 .. 20 ) {
            print '.';
            sleep 1;
        }
    }
    

    【讨论】:

    • 感谢您推荐这篇文章。 :)
    • $|--01 之间切换值,$|++$| 设置为1(即使前面有$| = -1;)。我确实不鼓励使用这些晦涩难懂的功能。
    【解决方案2】:

    Perl 和许多其他程序,默认情况下是行缓冲区输出。如果需要无缓冲输出,可以将$| 设置为1

    【讨论】:

      【解决方案3】:

      它没有清除缓冲区。如果 print 语句末尾有换行符,它会自动为您执行此操作:

      use warnings;
      
      for (1 .. 20) {
          print ".\n";
          sleep 1;
      }
      

      如果您不想要换行符(我不认为您想要),您可以使用特殊的自动刷新变量 $|。尝试将其设置为 1 或增加它。

      use warnings;
      
      $|++;
      
      for (1 .. 20) {
           print ".";
           sleep 1;
      }
      

      【讨论】:

        猜你喜欢
        • 2015-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 2014-01-03
        • 1970-01-01
        相关资源
        最近更新 更多