AutoHotkey 是否能够以基于零的顺序定义数组?

Is AutoHotkey capable of defining Arrays in a zero based order?

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

现在您可以声明一个数组并通过这样做使其从零开始:

arr := []
arr[0] := 1

上面的工作,如果我要求 arr[0] 它会 return 1。但是如果我使用 length() 方法它 returns 0,即使有一个值在那里!

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

arr := []
arr.push(3)

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

这可以吗?

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

我不相信这是可能的,因为论坛上有几个线程要求基于零的本地实现,但是 none 提供了一个解决方案。即使是演示了 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
    }
}