为什么这些甚至存在?这似乎很荒谬。与大多数动态语言一样,AppleScript类型似乎是不可变的原始类型,如integer
和real
s,它们将按值传递,并且与{{{{{}一起使用没有任何意义。 1}}或类似对象的类型,例如a reference to
s,application
s或script
s,它们已经通过引用传递。 record
如何不完全冗余?以下是Apple AppleScript语言指南(http://developer.apple.com/library/mac/#documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html如果您丢失链接)的示例:
a reference to
所以你的意思是告诉我,如果我这样做了,
tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"
appleScript运行时将发送一个发送到Finder进程的苹果事件告诉它,“嘿 - 有人刚要求你将/ dev / disks01的八位流返回给我!哈哈!我猜他应该问tell app "Finder" to set diskObj to startup disk
--result: startup disk of application "Finder"
它!让我们开始吧!这需要一段时间!“
我正在用Python编程,我这样做:
a reference to
我只是在内存中复制了一大堆数据吗?当然不是。但AppleScript中存在m = fileHandle.read( 1000000000 ) #and then wait a little while
n = m
意味着将对象分配给新变量是一种按值操作。如果是这样的话,那么a reference to
命令的处理是什么?
这里发生了什么?
更新:好吧,只是认为我是一个困惑的Python程序员。为了使这一点更清楚,我仍然认为
copy
是一个糟糕的例子(取自Applecript语言指南)。但是@ Chuck的tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"
示例属性本身持有一个可以重新分配的原始类型是更好的。 IOW,a reference to
对象实际上是一个变量/属性,它包含指向另一个变量或属性的指针。
答案 0 :(得分:3)
我的理解是你可以将引用视为指针。
set x = 5
set y to reference to x
set contents of y to 10
log x -- 10
通常,您不会手动创建引用。 AppleScript库和字典可能会返回它们,但您可以使用返回项的属性(例如name of startup disk
)。
查看this MacTech article以获取有关AppleScript参考的更详细讨论。
答案 1 :(得分:1)
AppleScript中的两个变量(如Python)可以共享相同的值。每个变量都有对其值的引用,但“引用”一词具有其他含义。字符串"https://stackoverflow.com/"
是对网站的引用;整数42
是道格拉斯亚当斯作品的参考; 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]
通过推迟访问列表的第2项。然后AppleScript中的contents of r
或Python中的r()
将获得该项目。 AppleScript还可以使用set contents of r to 99
设置项目; Python无法使用此lambda设置项目。 Python的lambdas可以做许多AppleScript的引用无法做到的事情。
a reference to
运算符 AppleScript Language Guide 描述了a reference to
运算符,但错过了一些重要的细节。运营商有一个操作数;编译器也接受reference OPERAND
或ref OPERAND
,然后将其重写为a reference to OPERAND
。
如果操作数是A of B
或B's A
形式的表达式,则运算符将表达式包装在类reference
的对象中。此表达式可以是item 2 of q
之类的元素,也可以是length of q
等属性。
如果操作数是变量,则运算符附加隐式my
或of 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()
此脚本的结果是{“一个字符串”,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
进行的。它只能起作用,因为代码位于运行处理程序中,其中bigList
和my 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
,一个脚本对象。