AutoHotkey能够以零为基础的顺序定义数组吗?

err*_*ven 2 arrays autohotkey prototype object

我经常对AutoHotkey不是基于零的语言这一事实​​感到沮丧.当您从其他语言翻译代码,或者甚至通过COM ScriptControl在JScript中与它们交互时,它不匹配.即使解析DOM元素,你必须考虑它们是零基础,似乎大多数语言都采用了基于零的数组.

现在,您可以通过执行以下操作声明一个数组并使其为零:

arr := []
arr[0] := 1
Run Code Online (Sandbox Code Playgroud)

上面的工作,如果我要求arr [0]它将返回1.但是如果我使用length()方法它返回0,即使那里有一个值!

如果我们声明然后push():

arr := []
arr.push(3)
Run Code Online (Sandbox Code Playgroud)

它总是从1开始存储,我想要改变它!

这可能吗?

err*_*ven 5

因为AutoHotkey是一种原型OOP语言(如JavaScript),所以你可以覆盖任何函数,甚至是内置函数.下面是重写Array()的演示,根据Lexikos,它是一个未记录的事实,它覆盖了定义数组[].

我不相信这是可能的,因为论坛上有几个线程要求零基于本地实现,但没有一个提供解决方案.甚至演示了覆盖Array()的线程也没有提到这是可能的!

作为奖励,我包括split()(基于零的StrSplit()函数),以帮助进一步展示此功能的无限可能性.

需要注意的是,我没有单元测试或实现任何方法覆盖,我可能忽略了一些东西,但我觉得这足以证明概念.此外,我毫不怀疑这会影响大型阵列的性能,特别是因为我为此演示实现了Length().

x := [] ; declare empty array
x.push("Zero Based rocks!") ; push message to the array.
msgbox % x[0] 

x := "" ; clear our Object
x := split("AutoHotkey with Zero Based Arrays")
msgbox % x.2 " " x.3 " " x.4 " " x.1 " " x.0 

Array(prm*) {
    x := {}
    loop % prm.length()
        x[A_Index -1] := prm[A_Index]
    x.base := _Array
    return x
}

split(x, dlm:="", opt:="") {
    r := []
    for k,v in StrSplit(x, dlm, opt)
        r.push(v)
    return r
}

Class _Array {

    ; Modified .length() to account for 0 index
    length() {
        c:=0
        for k in this
            c++
        return c
    }

    ; Modified .push() to start at 0
    push(x) {
        if (this.0 == "" && this.length() == 0)
            return this.0 := x
        else
            return this[this.MaxIndex()+1] := x
    }
}
Run Code Online (Sandbox Code Playgroud)