简体   繁体   English

`return` 在 AutoHotKey 中究竟做了什么?

[英]What exactly does `return` do in AutoHotKey?

In a comment chain , I ask: 在评论链中,我问:

Hmm, so the return doesn't play like a closing bracket like in other languages?嗯,所以return不像其他语言那样像右括号那样播放?

To which a user answers:用户回答:

It's maybe easy to think of return as just something that stops the code execution from going further.可能很容易将return视为阻止代码执行进一步执行的东西。 #IfDirectives don't care about return s, or anything else related to code execution, because they have nothing to do with code execution. #IfDirectives 不关心return或与代码执行相关的任何其他内容,因为它们与代码执行无关。 They are kind of just markers that enclose different parts of code within them它们只是将代码的不同部分包含在其中的标记

I have two questions from this:我有两个问题:

  1. If return is just something that stops code execution from going further, then how is it different to exit ?如果return只是阻止代码执行进一步的东西,那么exit有什么不同? They are both flow controls playing a role to determine The Top of the Script (the Auto-execute Section) .它们都是流控制,起到确定脚本顶部(自动执行部分)的作用。 I see that many people having this problem.我看到很多人都有这个问题。

  2. If return doesn't play like a closing bracket, then why does it appear in many places one expects a closing bracket?如果return不像右括号那样播放,那么为什么它会出现在许多人们期望右括号的地方? Especially when there is no subroutine involving in, like what is described in the formal definition.特别是当没有子程序涉及时,如正式定义中描述的那样。 Take this example in Hotkeys :Hotkeys为例:

     #n:: Run Notepad return

In AHK return is what you'd learn return to be from other programming languages.在 AHK 中, return是您从其他编程语言return到的。 It's just that control flow, and in general the legacy syntax, in AHK is different from what you might be used to from other languages.只是 AHK 中的控制流和一般的遗留语法与您可能习惯于其他语言的不同。

How is return different from exit ? returnexit有何不同?

If we're not trying to return a value from a function, and are just interested in the control flow, there is not much difference.如果我们不尝试从 function 中返回值,并且只是对控制流感兴趣,那么差别不大。 But the difference is there.但区别就在那里。

You could indeed end an hotkey label with exit , and it would be the same as ending it with return .您确实可以使用exit结束热键 label ,这与使用return结束相同。
From the documentation:从文档中:
"If there is no caller to which to return, Return will do an Exit instead." “如果没有要返回的调用者, Return将改为执行Exit 。” . .
I guess it's just convention to end hotkey labels with return .我想用return结束热键标签只是惯例。

So basically said, there is difference between the two, if return isn't about to do an exit .所以基本上说,两者之间是有区别的,如果return不打算做一个exit

Well when would this be?那么这会是什么时候呢?
For example:例如:

MsgBox, 1
function()
MsgBox, 3
return ;this does an exit

function()
{
    MsgBox, 2
    return ;this does a return
}

The first return has no caller to which to return to, so it will do an exit .第一个return没有要返回的调用者,因此它将执行exit
The second return however does have a caller to return to do, so it will return there, and then execute the 3rd message box.然而,第二个return确实有一个调用者要返回做,所以它会返回那里,然后执行第三个消息框。
If we replaced the second return with an exit , the current thread would just be exited and the 3rd message box would never have been shown.如果我们将第二个 return 替换为exit ,则当前线程将被退出,并且第三个消息框将永远不会显示。

Here's the same exact example with legacy labels:这是与旧标签相同的确切示例:

MsgBox, 1
gosub, label
MsgBox, 3
return ;this does an exit

label:
    MsgBox, 2
return ;this does a return

I'm showing this, because they're very close to hotkey labels, and hotkey labels were something you were wondering a lot about.我正在展示这个,因为它们非常接近热键标签,而热键标签是您非常想知道的东西。

In this specific example, if the line MsgBox, 3 didn't exist, replacing the second return with an exit would produce the same end result.在此特定示例中,如果行MsgBox, 3不存在,则将第二个return替换为exit将产生相同的最终结果。 But only because code execution is about to end anyway on the first return .但这只是因为代码执行在第一次return时无论如何都会结束。


If return doesn't play like a closing bracket, then why does it appear in many places one expects a closing bracket?如果return不像右括号那样播放,那么为什么它会出现在许多人们期望右括号的地方?

In AHK v1, hotkeys and hotstrings work like labels , and labels are legacy.在 AHK v1 中,热键和热字串的工作方式类似于标签,标签是遗留的。 Labels don't care about { } s like modern functions do.标签不像现代函数那样关心{ }
So we need something to stop the code execution.所以我们需要一些东西来停止代码执行。 Return does that. Return就是这样做的。

Consider the following example:考虑以下示例:

c::
    MsgBox, % "Hotkey triggered!"
    gosub, run_chrome
    ;code execution not ended

n::
    MsgBox, % "Hotkey triggered!`nRunning notepad"
    Run, notepad
    ;code execution not ended
    
run_chrome:
    MsgBox, % "Running chrome"
    run, chrome
    WinWait, ahk_exe chrome.exe
    WinMove, ahk_exe chrome.exe, , 500, 500
    ;code execution not ended

show_system_uptime:
    MsgBox, % "System uptime: " A_TickCount " ms"
    ;code execution not ended

We're not ending code execution at any of the labels.我们不会在任何标签处结束代码执行。 Because of this, code execution will bleed into other parts of the code, in this case, into the other labels.因此,代码执行会渗入代码的其他部分,在这种情况下,会渗入其他标签。
Try running the hotkeys and see how code execution bleeds into the other labels.尝试运行热键,看看代码执行如何渗入其他标签。

Because of this, the code execution needs to be ended somehow.因此,代码执行需要以某种方式结束。
If using { } was supported by labels, it would indeed be the solution to keep the code execution where it needs to be.如果标签支持使用{ } ,那么它确实是将代码执行保持在需要的位置的解决方案。
And in fact AHK v2 hotkeys and hotstrings are no longer labels (they're only lookalikes).事实上, AHK v2热键和热字串不再是标签(它们只是相似的)。 In v2 using { } is actually the correct way (the script wont even run if you don't use them).在 v2 中使用{ }实际上是正确的方法(如果您不使用它们,脚本甚至不会运行)。
See hotkeys from the AHK v2 documentation.请参阅 AHK v2 文档中的热键

Another answer above already gave a good explanation.上面的另一个答案已经给出了很好的解释。

So, to me:_所以,对我来说:_

( return vs Exit is like gosub vs goto -- return (literal meaning) vs terminate. ) return vs Exit就像gosub vs goto ——return (字面意思) vs terminate。)

return completes (ends) the current subroutine , and returns from the current subroutine back to the calling subroutine ; return完成(结束)当前subroutine ,并从当前subroutine返回到调用subroutine

Exit completes (ends) the current subroutine , and terminates (/exits /ends) the current thread (which discards all the previous calling subroutine ); Exit完成(结束)当前subroutine ,并终止(/exits /ends)当前thread (丢弃所有先前调用的subroutine );

  • where subroutines are inside a thread .其中subroutinesthread内。
    • ( subroutines are just like function calls or label calls (or hotkey label calls); you can visualize this as if method calls (stack frame) in Java (, you can see this when you debug in an IDE)) ( subroutines are just like function calls or label calls (or hotkey label calls); you can visualize this as if method calls (stack frame) in Java (, you can see this when you debug in an IDE))

Quotes:引号:

[] []

Return返回

Returns from a subroutine to which execution had previously jumped via function-call, Gosub, Hotkey activation, GroupActivate, or other means.从先前通过函数调用、Gosub、热键激活、GroupActivate 或其他方式跳转到的子例程返回。

https://www.autohotkey.com/docs/commands/Return.htm https://www.autohotkey.com/docs/commands/Return.htm

[] []

Exit出口

Exits the current thread or (if the script is not persistent) the entire script.退出当前线程或(如果脚本不是持久的)整个脚本。

https://www.autohotkey.com/docs/commands/Exit.htm https://www.autohotkey.com/docs/commands/Exit.htm

[] []

Gosub Gosub

Jumps to the specified label and continues execution until Return is encountered.跳转到指定的 label 并继续执行,直到遇到 Return。

https://www.autohotkey.com/docs/commands/Gosub.htm https://www.autohotkey.com/docs/commands/Gosub.htm

[] []

Goto

Jumps to the specified label and continues execution.跳转到指定的 label 并继续执行。

https://www.autohotkey.com/docs/commands/Goto.htm https://www.autohotkey.com/docs/commands/Goto.htm

[] []

main difference is gosub comes back, and goto does not.主要区别是 gosub 回来了,而 goto 没有。

https://www.autohotkey.com/board/topic/46160-goto-vs-gosub/ https://www.autohotkey.com/board/topic/46160-goto-vs-gosub/

[] []

A subroutine and a function are essentially the same thing一个子程序和一个 function 本质上是一回事

Difference between subroutine, co-routine, function and thread? 子程序、协程、function和线程的区别?

[] []

A subroutine is a portion of code which can be called to perform a specific task.子例程是可以调用以执行特定任务的代码部分。

Execution of a subroutine begins at the target of a label and continues until a Return or Exit is encountered.子程序的执行从 label 的目标开始,一直持续到遇到 Return 或 Exit。

Since the end of a subroutine depends on flow of control, any label can act as both a Goto target and the beginning of a subroutine.由于子程序的结束取决于控制流,因此任何 label 都可以作为 Goto 目标和子程序的开始。

https://www.autohotkey.com/docs/misc/Labels.htm#subroutines https://www.autohotkey.com/docs/misc/Labels.htm#subroutines

[] []

The current thread is defined as the flow of execution invoked by the most recent event;当前线程定义为最近事件调用的执行流程;

examples include hotkeys, SetTimer subroutines, custom menu items, and GUI events.示例包括热键、SetTimer 子例程、自定义菜单项和 GUI 事件。

The current thread can be executing commands within its own subroutine or within other subroutines called by that subroutine.当前线程可以在其自己的子例程中或在该子例程调用的其他子例程中执行命令。

https://www.autohotkey.com/docs/misc/Threads.htm https://www.autohotkey.com/docs/misc/Threads.htm


(you may try out the following code to see the difference) (你可以试试下面的代码看看有什么不同)

^r::
MsgBox, aaa 
gosub, TestLabel
MsgBox, bbb 
goto, TestLabel
MsgBox, ccc 
return

TestLabel:
MsgBox, inside
return
; Exit

Return returns from a function (called with funcname(...) syntax) or subroutine (called with Gosub label ).从 function(使用funcname(...)语法调用)或子程序(使用Gosub label调用) Return返回值。 Subroutines/functions can call other subroutines/functions and so it's convenient to end them with Return rather than Exit .子例程/函数可以调用其他子例程/函数,因此用Return而不是Exit结束它们很方便。 Exit ends the current thread of execution and won't transfer flow of control back to the caller. Exit结束当前的执行线程,并且不会将控制流转移回调用者。

For functions, Return also can return a value.对于函数, Return也可以返回一个值。

Return is not analogous to a closing bracket. Return右括号不同。 Closing brackets can occur only at the end of a function and imply a Return but you can also Return anywhere in a function.右括号只能出现在 function 的末尾并暗示Return ,但您也可以在 function 中的任何位置Return It is common to return in an If statement to "bail out" of a function early, perhaps if some parameter had an invalid value.通常在If语句中返回以提前“纾困” function,可能是因为某些参数的值无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM