📄 ch10_08.htm
字号:
<html><head><title>Loop Controls (Learning Perl, 3rd Edition)</title><link rel="stylesheet" type="text/css" href="../style/style1.css" /><meta name="DC.Creator" content="Randal L. Schwartz and Tom Phoenix" /><meta name="DC.Format" content="text/xml" scheme="MIME" /><meta name="DC.Language" content="en-US" /><meta name="DC.Publisher" content="O'Reilly & Associates, Inc." /><meta name="DC.Source" scheme="ISBN" content="0596001320L" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="Learning Perl, 3rd Edition" /><meta name="DC.Type" content="Text.Monograph" /></head><body bgcolor="#ffffff"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Learning Perl, 3rd Edition" /><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch10_07.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"></a></td><td align="right" valign="top" width="228"><a href="ch10_09.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr></table></div><h2 class="sect1">10.8. Loop Controls</h2><p><a name="INDEX-685" /> <a name="INDEX-686" />As you've surely noticed by now,Perl is one of the so-called "structured"<a name="INDEX-687" />programminglanguages. In particular, there's just one entrance to anyblock of code, which is at the top of that block. But there are timeswhen you may need more control or versatility than what we'veshown so far. For example, you may need to make a loop like a<tt class="literal">while</tt> loop, but one that always runs at leastonce. Or maybe you need to occasionally exit a block of code early.Perl has three loop-control operators you can use in loop blocks tomake the loop do all sorts of tricks.</p><a name="lperl3-CHP-10-SECT-8.1" /><div class="sect2"><h3 class="sect2">10.8.1. The last Operator</h3><p>The <tt class="literal">last</tt><a name="INDEX-688" /><a name="INDEX-689" /><a name="INDEX-690" /><a name="INDEX-691" /><a name="INDEX-692" /> operator immediately endsexecution of the loop. (If you've used the "break"operator in C or a similar language, it's like that.)It's the "emergency exit" for loop blocks. When youhit <tt class="literal">last</tt>, the loop is done. For example:</p><blockquote><pre class="code"># Print all input lines mentioning fred, until the __END__ markerwhile (<STDIN>) { if (/__END__/) { # No more input on or after this marker line last; } elsif (/fred/) { print; }}## last comes here ##</pre></blockquote><p>Once an input line has the <tt class="literal">__END__</tt><a name="INDEX-693" />marker, that loop is done. Of course, that comment line at the end ismerely a comment -- it's not required in any way. We justthrew that in to make it clearer what's happening.</p><p>There are five kinds of <a name="INDEX-694" />loop blocks in Perl. These are the blocksof <tt class="literal">for</tt>, <tt class="literal">foreach</tt>,<tt class="literal">while</tt>, <tt class="literal">until</tt>, or the nakedblock.<a href="#FOOTNOTE-229">[229]</a> The curly braces of an<tt class="literal">if</tt> block or subroutine<a href="#FOOTNOTE-230">[230]</a>don't qualify. As you may have noticed in the example above,the <tt class="literal">last</tt> operator applied to the entire loopblock.</p><blockquote class="footnote"> <a name="FOOTNOTE-229" /><p>[229]Yes, you can use <tt class="literal">last</tt> tojump out of a naked block. Be sure to check your local laws beforedoing so.</p> </blockquote><blockquote class="footnote"> <a name="FOOTNOTE-230" /><p>[230]It'sprobably not a good idea, but you could use these loop controloperators from inside a subroutine to control a loop that is<em class="emphasis">outside</em> the subroutine. That is, if a subroutineis called in a loop block, and the subroutine executes<tt class="literal">last</tt> when there's no loop block runninginside the subroutine, the flow of control will jump to just afterthe loop block <em class="emphasis">in the main code</em>. This ability touse loop control from within a subroutine may go away in a futureversion of Perl, and no one is likely to miss it.</p> </blockquote><p>The <tt class="literal">last</tt> operator will apply to the innermostcurrently running loop block. To jump out of outer blocks, staytuned; that's coming up in a little bit.</p></div><a name="lperl3-CHP-10-SECT-8.2" /><div class="sect2"><h3 class="sect2">10.8.2. The next Operator</h3><p><a name="INDEX-695" />Sometimes you're not ready for theloop to finish, but you're done with the current iteration.That's what the <tt class="literal">next</tt><a name="INDEX-696" /> operator is good for. It jumps to the<em class="emphasis">inside</em> of the bottom of the current loopblock.<a href="#FOOTNOTE-231">[231]</a> After<tt class="literal">next</tt>, control continues with the next iteration ofthe loop (much like the "continue" operator in C or asimilar language):</p><blockquote class="footnote"> <a name="FOOTNOTE-231" /><p>[231]This is another of our many lies. In truth,<tt class="literal">next</tt> jumps to the start of the (usually omitted)<tt class="literal">continue</tt><a name="INDEX-697" /> block for the loop. Seethe<a name="INDEX-698" /> <em class="emphasis">perlsyn</em>manpage for the full details.</p> </blockquote><blockquote><pre class="code"># Analyze words in the input file or fileswhile (<>) { foreach (split) { # break $_ into words, assign each to $_ in turn $total++; next if /\W/; # strange words skip the remainder of the loop $valid++; $count{$_}++; # count each separate word ## next comes here ## }}print "total things = $total, valid words = $valid\n";foreach $word (sort keys %count) { print "$word was seen $count{$word} times.\n";}</pre></blockquote><p>This one is a little more complex than most of our examples up tothis point, so let's take it step by step. The<tt class="literal">while</tt> loop is reading lines of input from thediamond operator, one after another, into <tt class="literal">$_</tt>;we've seen that before. Each time through that loop, anotherline of input will be in <tt class="literal">$_</tt>.</p><p>Inside that loop, the <tt class="literal">foreach</tt> loop is iteratingover the return value <tt class="literal">split</tt>. Do you remember thedefault for <tt class="literal">split</tt> with no arguments?<a href="#FOOTNOTE-232">[232]</a> Thatsplits <tt class="literal">$_</tt> on whitespace, in effect breaking<tt class="literal">$_</tt> into a list of words. Since the<tt class="literal">foreach</tt> loop doesn't mention some othercontrol variable, the control variable will be <tt class="literal">$_</tt>.So, we'll see one word after another in <tt class="literal">$_</tt>.</p><blockquote class="footnote"><a name="FOOTNOTE-232" /><p>[232]If you don't remember it, don't worry too much.Don't waste any brain cells remembering things that you canlook up with <i class="command">perldoc</i>.</p> </blockquote><p>But didn't we just say that <tt class="literal">$_</tt> holds oneline of input after another? Well, in the outer loop, that'swhat it is. But inside the <tt class="literal">foreach</tt> loop, it holdsone word after another. It's no problem for Perl to reuse<tt class="literal">$_</tt> for a new purpose; this happens all the time.</p><p>Now, inside the <tt class="literal">foreach</tt> loop, we're seeingone word at a time in <tt class="literal">$_</tt>.<tt class="literal">$total</tt> is incremented, so it must be the totalnumber of words. But the next line (which is the point of thisexample) checks to see whether the word has any nonwordcharacters -- anything but letters, digits, and underscores. So,if the word is <tt class="literal">Tom's</tt>, or if it is<tt class="literal">full-sized</tt>, or if it has an adjoining comma, quotemark, or any other strange character, it will match that pattern andwe'll skip the rest of the loop, going on to the next word.</p><p>But let's say that it's an ordinary word, like
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -