为什么AutoHotkey不支持参数列表中间的默认参数?

Syn*_*ech 4 autohotkey default-value optional-parameters

在AutoHotkey中,您可以在内置函数调用的中间省略参数,如下所示:

MsgBox, 4,, Blah
MouseGetPos,,, MouseWin
Run Code Online (Sandbox Code Playgroud)

您还可以使用可选参数àlaC++创建函数:

Foobar(baz, blah="something")
{
  MsgBox baz=%baz%, blah=%blah%
}
Run Code Online (Sandbox Code Playgroud)

但是文档说,在创建函数时,在默认参数之后不能有非默认参数.尝试这样做会导致解释器错误,说明默认参数后的第一个非默认参数需要默认值.

为什么?这样称呼它有什么问题?

Foobar(baz, blah="something", blivet)
{
  MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}

Foobar("cat",,"dog")
Run Code Online (Sandbox Code Playgroud)

有没有办法在中间创建带可选参数的函数?

Lex*_*kos 7

当你在内置命令(不是函数)中省略参数时,你真正在做的是传递一个空字符串.这两种情况之间存在差异:

  • 使用可选参数和强制参数定义函数.
  • 调用带有省略的可选参数的命令,后跟可选参数,这些参数尚未省略.

使用MsgBox和MouseGetPos,所有参数都是可选的.

AutoHotkey 1.1允许以下用户定义的功能:

Foobar(1,, 3)
Foobar(baz, blah="something", blivet="")
{
    MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}
Run Code Online (Sandbox Code Playgroud)

这仅在参数的默认值已知时才有可能(即不是动态调用函数时).


允许省略middle参数

如果你不想改变参数的顺序或者让三个选项中的两个可选,你可以做一些"杂耍":

Foobar("baz", "blivet")
Foobar("baz", "blah", "blivet")
Foobar(baz, p2, p3="omitted")
{
    blah := p3="omitted" ? "default" : p2   ; optional
    blivet := p3="omitted" ? p2 : p3        ; required
    MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}
Run Code Online (Sandbox Code Playgroud)

这样,该函数总是至少需要两个参数,并且在调用函数时可以有效地省略中间的参数.但是,您需要保留(字符串或数字)值以指示已省略参数.使用可变参数函数可以通过AutoHotkey 1.1避免这种情况:

Foobar("baz", "blivet")
Foobar("baz", "blah", "blivet")
Foobar(baz, p2, p3*)
{
    blah := p3.MaxIndex() ? p2 : "default"   ; optional
    blivet := p3.MaxIndex() ? p3[1] : p2     ; required
    MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}
Run Code Online (Sandbox Code Playgroud)

或者,可以将该函数声明为,Foobar(baz, p*)并且您可以基于条件p.MaxIndex()(附加参数的数量),但在这种情况下,只有第一个参数是必需的.


Joe*_* DF 2

两种选择...(解决方法...)

1.将所有带有默认值的参数放在右侧...

Foobar(baz, blivet, blah="something")
{
  MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}

Foobar("cat","dog")
Run Code Online (Sandbox Code Playgroud)

2. 定义一个“空”默认值...

Foobar(baz, blah="something", blivet="")
{
  MsgBox baz=%baz%, blah=%blah%, blivet=%blivet%
}

Foobar("cat",,"dog")
Run Code Online (Sandbox Code Playgroud)

我不能说为什么会这样,但现在,没有其他办法...(除非你修改 autohotkey :P )
我猜内置函数的工作方式不一样。