Site icon KerKer 的模組世界

[Batch] 延遲變數DelayedExpansion

&NewLine;<p class&equals;"wp-block-paragraph">邊做邊學,順便留個筆記,若有錯誤請不吝指教。<&sol;p>&NewLine;&NewLine;&NewLine;&NewLine;<&excl;--more-->&NewLine;&NewLine;&NewLine;&NewLine;<p class&equals;"wp-block-paragraph">Windows batch在變數的處理邏輯上與我們常用的程式語言存在一些落差,<br>最常見的是在處理迴圈及陣列的時候,<br>我們先看一個簡單的迴圈程式範例,<br>以下迴圈範例參考The Blue Nowhere的<a href&equals;"https&colon;&sol;&sol;bluenowhere334&period;blogspot&period;com&sol;2018&sol;06&sol;batch-enabledelayedexpansion&period;html&rpar;文章:" title&equals;"">文章<&sol;a>:<&sol;p>&NewLine;&NewLine;&NewLine;&NewLine;<pre class&equals;"wp-block-preformatted">Example&colon;&NewLine;set var&equals;0&NewLine;for &percnt;&percnt;a in &lpar;1 1 1 1 1&rpar; do &lpar;&NewLine; set &sol;a var&plus;&equals;&percnt;&percnt;a&NewLine; echo &percnt;var&percnt;&NewLine;&rpar;&NewLine;echo &percnt;var&percnt;<&sol;pre>&NewLine;&NewLine;&NewLine;&NewLine;<pre class&equals;"wp-block-preformatted">Output&colon;<br>0<br>0<br>0<br>0<br>0<br>5<&sol;pre>&NewLine;&NewLine;&NewLine;&NewLine;<p class&equals;"wp-block-paragraph">按照程式邏輯,我們認為for迴圈裏面echo出來的var值應該遞增,但是實際上卻輸出0。<br>在迴圈結束後再次輸出var值,卻看到var值有被正確的遞增到5。<br>這是因為Batch讀入for迴圈時會直接將變數值先全部填入,<br>所以實際上Batch認知for迴圈裡面的&&num;8221&semi;echo &percnt;var&percnt;&&num;8221&semi;在讀入時就會被理解成&&num;8221&semi;echo 0&&num;8243&semi;。<&sol;p>&NewLine;&NewLine;&NewLine;&NewLine;<p class&equals;"wp-block-paragraph">為了避免這個問題,我們就需要用到延遲變數展開&lpar;EnableDelayedExpansion&rpar;。<br>透過在程式的開頭加入setlocal EnableDelayedExpansion語句,<br>我們可以使用驚嘆號&lpar;&excl;&rpar;取代百分比&lpar;&percnt;&rpar;來標示變數,<br>驚嘆號標示的變數就會被延遲展開:<&sol;p>&NewLine;&NewLine;&NewLine;&NewLine;<pre class&equals;"wp-block-preformatted">Example&colon;&NewLine;setlocal EnableDelayedExpansion&NewLine;set var&equals;0&NewLine;for &percnt;&percnt;a in &lpar;1 1 1 1 1&rpar; do &lpar;&NewLine; set &sol;a var&plus;&equals;&percnt;&percnt;a&NewLine; echo &excl;var&excl;&NewLine;&rpar;&NewLine;echo &percnt;var&percnt;<&sol;pre>&NewLine;&NewLine;&NewLine;&NewLine;<pre class&equals;"wp-block-preformatted">Output&colon;<br>1<br>2<br>3<br>4<br>5<br>5<&sol;pre>&NewLine;&NewLine;&NewLine;&NewLine;<p class&equals;"wp-block-paragraph">這裡的&&num;8221&semi;echo &excl;var&excl;&&num;8221&semi;就能夠被Batch理解成每次執行到的時候動態抓取變數值了!<&sol;p>&NewLine;&NewLine;&NewLine;&NewLine;<p class&equals;"wp-block-paragraph">另外一個常見的應用場景是陣列:<&sol;p>&NewLine;&NewLine;&NewLine;&NewLine;<pre class&equals;"wp-block-preformatted">Example&colon;<br>set num&equals;1&semi;<br>set list&lbrack;&percnt;num&percnt;&rsqb;&equals;2&semi;<br>echo num&equals;&percnt;list&lbrack;&percnt;num&percnt;&rsqb;&percnt;<&sol;pre>&NewLine;&NewLine;&NewLine;&NewLine;<pre class&equals;"wp-block-preformatted">Output&colon;<br>num&equals;num<&sol;pre>&NewLine;&NewLine;&NewLine;&NewLine;<p class&equals;"wp-block-paragraph">看起來Batch把&&num;8221&semi;&percnt;list&lbrack;&percnt;&&num;8221&semi;和&&num;8221&semi;&percnt;&rsqb;&percnt;&&num;8221&semi;理解成變數了,<br>所以這裡需要另一種符號來與百分號做區隔,<br>所以我們可以改成這樣:<&sol;p>&NewLine;&NewLine;&NewLine;&NewLine;<pre class&equals;"wp-block-preformatted">Example&colon;<br>setlocal EnableDelayEdexpansion<br>set num&equals;1&semi;<br>set list&lbrack;&percnt;num&percnt;&rsqb;&equals;2&semi;<br>echo num&equals;&excl;list&lbrack;&percnt;num&percnt;&rsqb;&excl;<&sol;pre>&NewLine;&NewLine;&NewLine;&NewLine;<pre class&equals;"wp-block-preformatted">Output&colon;<br>num&equals;2<&sol;pre>&NewLine;&NewLine;&NewLine;&NewLine;<p class&equals;"wp-block-paragraph">在&&num;8221&semi;echo num&equals;&excl;list&lbrack;&percnt;num&percnt;&rsqb;&excl;&&num;8221&semi;中,<br>Batch讀入時會先理解成&&num;8221&semi;echo num&equals;&excl;list&lbrack;1&rsqb;&excl;&&num;8221&semi;,<br>再延遲展開list&lbrack;1&rsqb;的值,<br>這樣就可以正確輸出了~<&sol;p>&NewLine;

Exit mobile version