美文网首页AHK程序设计
[基础] 代码语句与代码块 - 老司机也会翻车的地方

[基础] 代码语句与代码块 - 老司机也会翻车的地方

作者: d61f25068828 | 来源:发表于2018-11-17 00:33 被阅读3次

[基础] 代码语句与代码块 - 老司机也会翻车的地方

文章编号-AHK-J005

从一个诡异的案例讲起,代码如下。
您看完后猜猜是哪一个MsgBox会运行。

Haystack = abcdefghijklmnopgrs 
Needle = abc 
;# 检查变量是否包含指定的字符串.
IfInstring,Haystack,%Needle% {
    MsgBox,% "The string was found " ;MsgBox_1
return
}
else
    MsgBox,% "The string was not found " ;MsgBox_2

震惊:风格差异导致语义差异

我第一次看到这个案例的时候,我觉得一定是MsgBox_1运行,因为abc明显包含于Haystack,但是当我实际来测试的时候发现居然不是,而是提示我 Error: Unexpected "}" At line 4

看到提示之后,我瞪着眼看了好几次,但是发现括号的确是成双成对的,所以十分不解。


无语了.gif

后来翻看案例,发现如果‘{’不另起一行的话,程序就会匹配不到括号从而出现错误,而且这种现象只在某些命令中出现。

记得Java中有两种代码风格,分别是“行尾风格”和“次行风格”,简单举一个例子。所谓的“行尾/次行”指的是代码块中第一个花括号的位置。以下分别举出Java和AHK的例子。

//示例 AHK-J005-1
//Java代码
        int a=0,b=1;
        ;# 行尾风格
        if(a>b){
            System.out.println("大于");   
        }
        ;# 次行风格
        if(a>b)
        {
            System.out.println("大于");
        }
;示例 AHK-J005-2
;# 行尾风格
IfInstring,Haystack,%Needle% {
Msgbox,包含
}

;# 次行风格
IfInstring,Haystack,%Needle% 
{
Msgbox,包含
}

在Java中用哪种完全是依照读者的喜好,从语义上没有任何差异,语法上没有任何错误,只不过由于标准库里面的代码主要都是采用行尾风格,所以说基本上大家都喜欢这个,我也不例外。

但是在AHK中,绝大多数命令都是不能使用行尾风格的。

能够使用行尾风格的分别是:

  1. 函数的定义
  2. 异常的抛出与捕获(Try,Catch,Finally)
  3. 表达式形式的if-else
  4. 循环while,for,loop(普通)

小结:① 在Java中,风格的不同不会导致语义问题,但是在AHK中确会导致语义问题。② 在AHK中,有关于“函数以及类定义/表达式”的可以使用“行尾风格”,其他则不可使用。

深挖:导致该问题可能的原因是什么?

我猜测可能还是AHK的两套系统遗留下来的问题,命令系统中,参数是直接用逗号隔开的,如果在同一行,放着一个其他符号,那么就很难判断这个符号到底是属于参数还是命令,所以祖传的命令系统都是次行。
但是新的表达式系统,参数的列表被括号所包裹,所以就不存在这个问题,反而次行风格更受欢迎,因为它的可读性是更好的。

;示例 AHK-J005-3
;# 行尾风格

Haystack = abcdefghijklmnopgrs 
Needle = abc 

IfInstring,Haystack,%Needle% {
Msgbox,包含
}

;# 次行风格
IfInstring,Haystack,%Needle% 
{
Msgbox,包含
}

if InStr(Haystack, Needle){
Msgbox,包含
}

if InStr(Haystack, Needle)
{
Msgbox,包含
}

小结:造成上述问题的原因很可能还是AHK颇有特点的“命令/表达式”二元结构。

语句:一个像空气一样的概念

语句简单来说就是程序运行的最小单位。

自从学习AHK以来,我就没有管过这个概念,在帮助文档中也极少会看到。但是当我拿起Java和AHK的代码时,却发现了差异,Java的每个语句的结尾必然是‘;’,所以在Java中,换号所起的主要作用就是增加可读性,如果你愿意,你可以把所有的内容写成几行。但是AHK中就不是,因为他们没有明显的语句分隔符。

很难想象语句会没有分隔,那么最大的可能性就是“分隔符是换行”,[后来我在帮助文档中也查到了这一部分。][1]
[1]: https://wyagd001.github.io/zh-cn/docs/Language.htm#general-conventions

在Java中可以这么做,对于很短的句子来说,这样的表达显然更简洁。

//示例-AHK-J004
int Haystack=2,line=3,count=0;
Haystack+=2;line+=3;count++;

但是AHK中也并非完全不行,在某些情况下也是可以的(count1那一段)。

;示例-AHK-J005
count0=0 ,face=0,count++,face++
count1:=0,face:=0,count++,face++
MsgBox,% count0
MsgBox,% count1
MsgBox,% face

这被称为 “逗号(多语句) [v1.0.46+]”,它可以把多个表达式联合在一起使用,而且官方特别强调了,该方法对于运行效率的提高是很有帮助的。

小结:AHK中的语句分隔符就是换行本身,由于换行符本身是个透明的东西,所以在AHK中这个概念已非常弱化。其实,AHK也能够使用多语句,而且对提高效率有帮助。

妥协:手动换行和延续片段

上面说过,在Java中换行的最大作用其实就是做代码的可读性提升,本身几乎是没有什么作用,但是AHK中却是非常重要的。

所以如果要手动换行的话,Java在大多数情况下,都可以直接按下回车键就解决,AHK该怎么办呢?

AHK给出了一些变通的方法,也就是只要在行首出现,除了“自增自减”之外的任何运算符,都看成“行延续”,(虽然我不常用,但是我感觉这种方法对可读性的伤害还是不小的,如果你要用的话,建议只用固定的一种符号)。

另外,AHK而对于大批量的字符串进行了一下优化,这一部分就不讲了,因为和全文内容关系不是特别大,叫做“延续片段”,在这个模式下换行符的作用就单纯是字符,没有语句分隔作用。

小结:为了解决手动换行符的问题,AHK简单粗暴的规定,只要在开头加入运算符,都算是行延续。

(^-^)V

全文技术总结

  1. 在AHK中书写代码风格差异会直接影响语义,在调用命令时应特别注意要使用“次行风格”,不遵守将会导致程序出现严重错误。
  2. AHK中的换行其实是语句分隔符。但是在表达式系统中可以实现“多语句”并排,而且能够提高运算效率,有很大程度上提高了可读性,建议使用。
  3. AHK中为了解决由于“换行被当做语句分隔符”所造成的手动换行不方便的问题,提供了一个可读性比较差的解决方案,也就是“除了自增自减运算符之外的一切运算符,只要在行的开头都可以作为行延续的标志”。我建议尽量不要使用这种方法,如果要使用的话,也要先规定一个具体运算符,并且一直使用下去。
  4. 如果遇到大批量字符串操作,建议使用“延续片段”。

End

心如止水是Java/AHK的持续学习者,很欢迎您来和我探讨Java/AHK问题。 QQ:2531574300 ^_^

更多文章:

[专栏] AHK程序设计 - SegmentFault 思否(优先持续更新)
[AHK经验] 动态调用本地库lib,必须显式声明
[基础] AHK函数对象系列-绑定方法对象
[基础] [GIF动图] 绕过中文输入法发送文本的3种方法

问题解答:

[问题解答] 示例不能运行吗? - 关于AHK程序设计系列文章示例问题的解释

版权声明:

该文章版权系“心如止水”所有,欢迎分享、转发,但如需转载,请联系QQ:2531574300,得到许可并标明出处和原链接后方可转载。未经授权,禁止转载。

文章版本:

v1_11月17日

AHK版本:1.1.30.00

作者:心如止水

相关文章

  • [基础] 代码语句与代码块 - 老司机也会翻车的地方

    [基础] 代码语句与代码块 - 老司机也会翻车的地方 文章编号-AHK-J005 从一个诡异的案例讲起,代码如下。...

  • [列表] 心如止水的AHK文章列表

    AHK基础知识系列 [基础] 代码语句与代码块v2[基础] [GIF动图] 绕过中文输入法发送文本的3种方法[基础...

  • day4-if语句、for, while,break,conti

    if语句 1.1 if if 条件语句:代码块其他与句 执行过程:先判断条件语句是否为true,如果是就执行代码块...

  • 控制语句总结

    #if语句 语法:if(判断){代码块}else{代码块} if(){}else if()。。。。。 if语句是万...

  • for循环中++i和i++的区别

    语法 语句 1 在循环(代码块)开始前执行 语句 2 定义运行循环(代码块)的条件 语句 3 在循环(代码块)已被...

  • python-day4

    1.if语句 1.if if 条件语句:代码块其他与句执行过程:先判断条件语句是否为True,如果是执就行代码块,...

  • java中的代码块

    java中的代码块: 普通代码块,静态代码块,构造代码块 1. 普通代码块:在方法或者语句中, …… ...

  • js遍历循环for/for...in/for...of/forE

    【1】for循环 语句 1 在循环(代码块)开始前执行语句 2 定义运行循环(代码块)的条件语句 3 在循环(代码...

  • day4-循环

    一、if语 结构 if 条件语句1:代码块1elif 条件语句2:代码块2else:代码块3其他语句执行过程:先判...

  • 24,代码块

    代码块: 普通代码块:在方法或语句中出现的{}就称为普通代码块。普通代码块和一般语句的执行顺序由他们在代码中出现的...

网友评论

    本文标题:[基础] 代码语句与代码块 - 老司机也会翻车的地方

    本文链接:https://www.haomeiwen.com/subject/ljzvfqtx.html