美文网首页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

    作者:心如止水

    相关文章

      网友评论

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

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