Reference AppleScript引用对象-帮助我理解它们
为什么会存在这些呢?这似乎很荒谬。与大多数动态语言一样,AppleScript类型似乎要么是不可变的基本类型,如Reference AppleScript引用对象-帮助我理解它们,reference,applescript,pass-by-reference,appleevents,Reference,Applescript,Pass By Reference,Appleevents,为什么会存在这些呢?这似乎很荒谬。与大多数动态语言一样,AppleScript类型似乎要么是不可变的基本类型,如integers和reals,它们将按值传递,并且与引用一起使用没有任何意义,要么是对象类型,如applications、scripts,或记录s,它们已通过引用传递。对的引用怎么不是完全冗余的?下面是一个来自苹果的AppleScript语言指南的示例(如果您丢失了链接): 你的意思是说如果我这样做 tell app "Finder" to set diskObj to startup
integer
s和real
s,它们将按值传递,并且与引用一起使用没有任何意义,要么是对象类型,如application
s、script
s,或记录
s,它们已通过引用传递。对
的引用怎么不是完全冗余的?下面是一个来自苹果的AppleScript语言指南的示例(如果您丢失了链接):
你的意思是说如果我这样做
tell app "Finder" to set diskObj to startup disk
--result: startup disk of application "Finder"
applescript运行时将向Finder进程发送一个apple事件,告诉它,“嘿,有人刚刚让你将/dev/disks01的八位字节流返回给我!哈哈!我想他应该要求引用它!让我们开始吧!这需要一段时间!”
我正在用Python编程,我这样做:
m = fileHandle.read( 1000000000 ) #and then wait a little while
n = m
我只是在内存中复制了一格数据吗?当然不是。但是AppleScript中存在对
的引用,这意味着将对象分配给新变量是一种按值操作。如果是这样的话,copy
命令的作用是什么
这是怎么回事
更新:好吧,把我当成一个困惑的Python程序员。我还是想说清楚一点
tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"
是一个糟糕的例子(摘自applescript语言指南)。但是@Chuck的引用属性本身的例子是一个更好的例子,该属性本身包含一个可以重新分配的基元类型。依我看,引用
对象实际上是一个变量/属性,它包含指向另一个变量或属性的指针。我的理解是,可以将引用视为指针
set x = 5
set y to reference to x
set contents of y to 10
log x -- 10
通常,您不会手动创建引用。AppleScript库和字典可能会返回它们,但是您可以使用返回项的属性(例如启动盘的名称)
老实说,我不理他们。在使用AppleScript的二十年中,我可能不得不查找一次参考文献。如果您试图在AppleScript中执行某些操作,并且认为需要创建一个引用变量,那么您可能没有以最直接的方式执行
查看有关AppleScript引用的更详细讨论。AppleScript中的两个变量(如Python中的变量)可以共享相同的值。每个变量都有对其值的引用,但“reference”一词有其他含义。字符串“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
就像蟒蛇一样
v = [11, 22, 33]
r = lambda: v[1]
通过延迟对列表第二项的访问。然后AppleScript中r的内容或Python中的r()
将获得该项。AppleScript还可以将项目设置为将r的内容设置为99
;Python无法使用此lambda设置项。Python的lambdas可以完成AppleScript引用无法完成的许多事情
对操作员的引用
描述了对
运算符的引用,但遗漏了一些重要的细节。运算符有一个操作数;编译器还接受引用操作数
或引用操作数
,然后将它们重写为对操作数的引用
如果操作数是形式为A of B
或B的A
的表达式,则运算符将表达式包装在类引用的对象中。此表达式可以是元素,如q的项2
,也可以是属性,如q的长度
如果操作数是变量,则运算符附加一个隐式的my
或of me
。例如,运行处理程序中对q的引用与对my q的引用相同。在q
和my q
不同的范围内,这会让人感到困惑
对于其他操作数,则运算符仅返回操作数。例如,对3的引用返回3,它不是引用
类的对象
运算符捕获变量的当前值。例如,对q的i项的引用
捕获i和q的值。相比之下,对q的引用不捕获q的值,因为它与对我的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
操作符来提高访问大列表的速度。指南使用
但未能解释该引用隐式地引用了我的bigList
,因此访问是通过脚本对象me
。它之所以有效,是因为代码在运行处理程序中,bigList
和mybiglist
是同一个列表
事实证明,如果引用通过任何脚本对象,访问大列表的速度都很快。其他访问速度较慢。下一个脚本通过使用快速访问创建一个包含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()
我在我的电脑上运行了这个脚本
set bigListRef to a reference to bigList
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()