4

为什么这些甚至存在?这似乎很荒谬。与大多数动态语言一样,AppleScript 类型似乎要么是不可变的原始类型,如integers 和reals,它们将按值传递并且与 一起使用没有任何意义a reference to,要么是类对象类型,如applications、scripts 或records,它们已经通过引用传递。怎么a reference to不完全冗余?这是取自 Apple 的 AppleScript 语言指南的示例(如果您丢失了链接,请参见http://developer.apple.com/library/mac/#documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html ):

tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"

所以你的意思是告诉我,如果我这样做,

tell app "Finder" to set diskObj to startup disk
--result: startup disk of application "Finder"

applescript 运行时将发送一个发送到 Finder 进程的苹果事件,告诉它,“嘿 - 有人刚刚要求你将 /dev/disks01 的八位字节流返回给我!哈哈!我想他应该问为a reference to它!让我们开始吧!这需要一段时间!”

我正在用 Python 编程,我这样做:

m = fileHandle.read( 1000000000 ) #and then wait a little while
n = m 

我只是在内存中复制了一些数据吗?当然不是。但是a reference toAppleScript 中的存在意味着将对象分配给新变量是按值操作。如果是这种情况,那么命令的处理是copy什么?

这里发生了什么?

更新:好吧,就当我是一个困惑的 Python 程序员吧。只是为了更清楚一点,我仍然认为

tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"

是一个糟糕的例子(取自applescript语言指南)。但是@Chuck 的a reference to属性本身包含一个可以重新分配的原始类型的示例是一个更好的示例。IOW,reference对象实际上是一个变量/属性,它包含指向另一个变量或属性的指针。

4

2 回答 2

3

我的理解是,您可以将引用视为指针。

set x = 5
set y to reference to x
set contents of y to 10
log x -- 10

通常,您不会手动创建参考。AppleScript 库和字典可能会返回它们,但随后您将使用返回项目的属性(name of startup disk例如)。

老实说,我会忽略它们。在使用 AppleScript 的 20 年中,我可能不得不查阅文档以参考一次。如果您尝试在 AppleScript 中做某事并认为您需要创建一个引用变量,那么您可能没有以最直接的方式进行操作。

查看这篇 MacTech 文章,了解有关 AppleScript 参考的更详细讨论。

于 2011-04-28T20:59:56.023 回答
2

AppleScript 中的两个变量与 Python 中一样,可以共享相同的值。每个变量都有一个对其值的引用,但“引用”这个词还有其他含义。该字符串"https://stackoverflow.com/"是对网站的引用;该整数42是对 Douglas Adams 作品的引用;AppleScript 中的类对象reference是一种不同的引用。

类的对象reference推迟对某个对象的元素或属性的访问。它几乎就像 Python 中的 lambda,因为 AppleScript

set v to {11, 22, 33}
set r to a reference to item 2 of v

像 Python 一样

v = [11, 22, 33]
r = lambda: v[1]

通过推迟访问列表的第二项。然后contents of r在 AppleScript 或r()Python 中将获得该项目。AppleScript 还可以使用set contents of r to 99;设置项目。Python 无法使用此 lambda 设置项目。Python 的 lambda 可以做很多 AppleScript 的引用不能做的事情。

a reference to操作员

AppleScript 语言指南描述了操作符,a reference to遗漏了一些重要的细节。运算符有一个操作数;编译器也接受reference OPERANDor ref OPERAND,然后将它们重写为a reference to OPERAND.

如果操作数是A of Bor形式的表达式B's A,则运算符将表达式包装在 class 的对象中reference。这个表达式可以是一个元素,比如item 2 of q,也可以是一个属性,比如length of q

如果操作数是变量,则运算符附加隐含的myorof me。例如,a reference to q在运行处理程序中与a reference to my q. q这在不同的范围内变得令人困惑my q

对于其他操作数,则运算符仅返回操作数。例如,a reference to 3返回 3,它不是类的对象reference

运算符捕获变量的当前值。例如,a reference to item i of q捕获 i 和 q 的值。相反,a reference to q不捕获 q 的值,因为它与 相同a reference to my q,所以它将 q 视为属性,而不是变量。

to demo()
    set q to {11, 22, 33}
    set rq to a reference to q
    set i to 2
    set ri to a reference to item i of q
    set i to 3
    set item 2 of q to 55
    set q to {77, 88, 99}
    {contents of rq, contents of ri}
end demo

set q to "a string"
demo()

该脚本的结果是 {"a string", 55}。引用 rq 忽略了本地 q 并my q从运行处理程序中使用。引用 ri 捕获了 i 和 q 的局部值,忽略了后面对 i 和 q 的赋值,但没有忽略对 q 的第 2 项的赋值。

使用带有大列表的引用

AppleScript 语言指南还提供了使用a reference to运算符来提高访问大列表速度的示例。该指南使用

set bigListRef to a reference to bigList

但未能解释引用是隐式a reference to my bigList的,因此访问是通过脚本对象me。它之所以有效,是因为代码在运行处理程序中,其中bigListmy bigList是同一个列表。

事实证明,如果引用通过任何脚本对象,访问大列表的速度会很快。其他访问速度很慢。下一个脚本通过使用快速访问创建一个包含 7000 个项目的列表,然后使用慢速和快速访问读取该列表来显示这一点。

to bench(what)
    set start to current date
    repeat with i from 1 to 7000
        if item i of what is not 42 then
            error "wrong value"
        end if
    end repeat
    (current date) - start
end bench

to bench2()
    script box
        property nums : {}
    end script
    repeat 7000 times
        set end of box's nums to 42
    end repeat
    {bench(box's nums), bench(a reference to box's nums)}
end bench2

bench2()

我在运行 PowerPC Mac OS X 10.4.11 的旧机器上运行了这个脚本。结果是 {19, 0},所以慢速访问需要 19 秒,快速访问需要 0 秒。

该线路set end of box's nums to 42无需操作员即可快速访问a reference to。它很快,因为访问通过box一个脚本对象。

于 2017-10-23T21:10:58.087 回答