Board logo

标题: [数值计算] 批处理延迟环境变量扩容和直接变量扩容有什么区别? [打印本页]

作者: sdurain    时间: 2011-8-19 22:33     标题: 批处理延迟环境变量扩容和直接变量扩容有什么区别?

刚开始接触批处理,在看set命令帮助文件中发现一个问题,请教一个延迟环境变量扩容和直接变量扩容的区别:
在帮助文件中,有以下一段代码:
  1.     set VAR=before
  2.     if "%VAR%" == "before" (
  3.         set VAR=after
  4.         if "%VAR%" == "after" @echo If you see this, it worked
  5.     )
复制代码
按我的理解,程序执行的时候都是按照代码中的次序依次执行的,最后的结果应该是输出"If you see this, it worked”
但是帮助文件中给出的解释是:
不会显示消息,因为在读到第一个 IF 语句时,BOTH IF 语句中
的 %VAR% 会被代替;原因是: 它包含 IF 的文体,IF 是一个
复合语句。所以,复合语句中的 IF 实际上是在比较 "before" 和
"after",这两者永远不会相等。
有朋友给详细介绍下为什么吗?谢谢
作者: raymai97    时间: 2011-8-19 22:49

很简单
比如以下代码
  1. if not exist a.txt (
  2. set result=lol
  3. echo result is %result%
  4. pause
  5. )
复制代码
你会发现它只显示result is
其实就是因为没有变量延迟的关系
没有延迟变量时,在括号里面的set其实并没有立刻执行
如果有用setlocal enabledelayedexpansion 来启用设置变量延迟的话,
就会立刻执行~

所以如果你在括号之外echo,就会显示result is lol

其实论坛里面有很多关于这个的,楼主自己去找找看吧~
作者: 冷玉公子    时间: 2011-8-19 23:37

  1. @Echo Off&SetLocal EnableDelayedExpansion
  2. Set Var=before
  3. if "%Var%" == "before" (
  4. Set Var=after
  5. if "!Var!" == "after" echo If you see this, it worked
  6. )
复制代码
if "!Var!" == "after" echo If you see this, it worked

打开变量延迟就可以了,然后命令修改的变量要用感叹号来表示变量。
论坛专门有一篇文章是介绍变量延迟的。
建议你先搜索下。
作者: Hello123World    时间: 2011-8-20 14:32

本帖最后由 Hello123World 于 2011-8-20 14:38 编辑

诚如3楼所言,开启变量延迟即可。
  1. @echo off
  2.     set VAR=before
  3.     if "%VAR%" == "before" (
  4.         set VAR=after
  5.         if "%VAR%" == "after" @echo If you see this, it worked
  6.     )
  7. pause
复制代码
之所以不会显示“If you see this, it worked”,是因为
  1.    if "%VAR%" == "before" (
  2.         set VAR=after
  3.         if "%VAR%" == "after" @echo If you see this, it worked
  4.     )
复制代码
是一个复合语句(复合语句的意思就是,这一整个语句看起来很多行,但其实就是一条语句),而批处理的执行规则就是“至上而下,逐条执行。”,前面已经赋值    set VAR=before,所以%VAR%的值就为before,即便在复合语句中 set VAR=after 为%VAR%重新赋值,但是在这一条语句中%VAR%的值还是紧接上一条语句set VAR=before,所以
  1. 实际上是在比较 "before" 和
  2. "after",这两者永远不会相等。
复制代码
这也算是批处理的一种特性吧,vbs、vb之类的语言就没有这种“变量延迟”。

例如,vb,这里显示的是a=2
  1. Option Explicit
  2. Private Sub Command1_Click()
  3.     Dim a
  4.     a = 1
  5.     If a = 1 Then
  6.         a = 2
  7.         MsgBox a
  8.     End If
  9. End Sub
复制代码

作者: sdurain    时间: 2011-8-22 14:41

多谢各位朋友的解答和版主的详细解释,正在看论坛的精华帖和从入门到精通系列,收获颇多,多谢!




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2