AppleScript学习笔记(二)AppleScript的四种数据类型

简介

本文介绍AppleScript变量其中的四种数据类型:number,string,list和record。其中list和record由dialog分析导出。

AppleScript中的变量名由一个词组成,中间不能留有空格。不能以数字开头,但数组可以在变量名中出现。命名允许使用下划线“_”。




Number(数字)

分为整数和分数两大类,二者都可以是负数。

为变量赋值应当使用set to语句(个人感觉这段语法有点奇怪):set 变量名 to 变量值

number类型变量之间可以进行四则运算和乘方运算等:

-- set number and calculate
set x to 10
set y to 10
set xy to x * y
set x3 to y ^ 3

输出结果是xy = 100,x ^ 3 = 1000.0。输出结果可以在运行结果区中看到(只看到最后一行的变量值):

AppleScript学习笔记(二)AppleScript的四种数据类型




String(字符串)

1.使用set to语句赋值

字符串类型也非常简单,对其赋值也是使用set to语句。例如:

-- set string
set emptyString to ""
set aSpaceString to " "
set helloString to "Hello"
set AppleScriptString to "AppleScript"

2.使用&运算符连接

可以使用“&”运算符将几个字符串连结在一起:

-- string & string
set stringAndString to helloString & aSpaceString & AppleScriptString

其输出结果为:

"Hello AppleScript"

用双引号引起来表示这是字符串值。

如果想在字符串中输出引号怎么办?用转义字符“ \ ”。例如:

-- \"
set exampleString to "\"Excuse me\""
display dialog exampleString

对话框的提示文字多了引号:

AppleScript学习笔记(二)AppleScript的四种数据类型


如果想在字符串中显示“\”呢?再加一个反斜杠就可以了,例如:

-- \display dialog "blah blah \\\" blah"

AppleScript学习笔记(二)AppleScript的四种数据类型


3.获取字符串变量的长度

使用关键字the length of来获取:

-- length of string
set lengthOfString to the length of stringAndString

输出结果为17,可见空格也是计算在内的。


4.number和string之间的类型互换

如何将number转换为string类型?或将string类型转换为number类型?使用“as 类型名”来显式声明就可以了:

set numberToString to 100 as string
set stringToNumber to "10" as number




Dialog(对话框)

在介绍list和record之前,必须加入一个小插曲:dialog。list和record是dialog中非常重要的两个组成部分,因此我们先来看看对话框的使用方法。

dialog的调用格式为:

display dialog "提示文字" buttons {"按钮1", "按钮2", ...} default button "按钮名"

除了提示文字外后面的都可以缺省。

下面来看一些调用的例子:

-- display dialog
display dialog "Welcome to AppleScript"
display dialog helloString
display dialog stringAndString

其中一个弹出的对话框为(这里弹了3个):

AppleScript学习笔记(二)AppleScript的四种数据类型

在缺省情况下,按钮列表为“取消”和“好”,默认按钮为“好”。

点击“好”后,结果输出为:

{button returned:"好"}

这里就涉及到了list和record的概念。在指定按钮列表时使用了list类型,而在点击了按钮后返回的结果就是record类型。(list类似于数组,元素可以是任意类型数据。record类似于字典,上面的button returned就是key,“好”就是value)

当然,我们也可以使用上下文菜单快捷插入一个菜单模板:

AppleScript学习笔记(二)AppleScript的四种数据类型




List(列表)

接下来开始介绍列表的内容。

列表的表示格式为:{"item1", "item2", "item3"},这里只列出了3项,列表中元素的个数可以是0也可以是任意多个。列表中的元素可以是任意数据类型变量。


1.使用set to语句赋值

set firstList to {100, 200.0, "Number", -10}
set emptyList to {}

其中firstList在结果区输出为:{100, 200.0, "Number", -10}


list中也可以包含list,例如:

set listOfList to {1, "2", firstList}

结果输出为:{1, "2", {100, 200.0, "Number", -10}}


2.使用&连接列表

使用&运算符可以直接将若干个列表中的元素合并并形成一个新的列表:

-- list and list
set addToBeginList to {1}
set addToEndList to {6}
set currentList to {2, 3, 4, 5}
set modifiedList to addToBeginList & currentList & addToEndList

结果输出为:{1, 2, 3, 4, 5, 6}


3.获取和更改列表中的元素

(1)获取list中指定序号的元素有多种方法,例如:

set item 2 of modifiedList to "2"
set the second item of modifiedList to "second"
set the 2nd item of modifiedList to "2nd"

the second item或the 2nd item这种写法,如果超过10就会出现错误(小弟对于那些序数词的规则也忘了很多),所以最好还是用第一种方式:item 序号。


(2)可以为列表中的随机元素赋值,使用some item of关键字就可以了,例如:

set randomX to some item of modifiedList

可以看到每次输出的结果不是固定的。


(3)可以用the last item关键字来获取列表中的最后一个元素,例如:

set lastItem to the last item of modifiedList

貌似没有the first item关键字。


(4)也可以用-1来获取最后一个元素,负数表示从列表尾端开始获取元素,例如:

set aList to {"hello", "hi"}
set aLastItem to item -2 of aList

结果输出为:"hello"


注意获取item时不要越界,item 0也不可以。


(5)获取整个列表,直接get就可以了(所有的变量类型同理),例如:

get modifiedList

结果输出为:{1, "2nd", 3, 4, 5, 6}


4.获取子列表

使用“items 开始序号 through 结束序号 of”可以获取list中的子列表,例如:

set longList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
set shortList to items 6 through 10 of longList

结果输出为:{6, 7, 8, 9, 10}

注意,从结束序号取到开始序号的方式获取的子列表是相同的,例如:

set shortList to items 10 through 6 of longList

结果输出为:{6, 7, 8, 9, 10}


要逆向获取子列表,需要用到reverse关键字,例如:

set reversedList to reverse of longList

结果输出为:{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}


5.获取列表的元素个数

使用length或count关键字均可,例如:

set listLength to the length of longList
set listCount to the count of shortList

结果为10和5。


6.添加元素到列表末尾

使用“set the end of 列表名 to 元素”实现,例如:

-- Add item to end of list
set listNotAdded to {1, 2, 3, 4}
set the end of listNotAdded to 5
set the end of listNotAdded to {6, 7, 8, 9, 10}
get listNotAdded

输出结果为:{1, 2, 3, 4, 5, {6, 7, 8, 9, 10}}


7.将string转换为list

方法就是在set to语句后加一个as list声明,例如:

-- string to list
set stringNotConvert to "string"
set convertStringToList to stringNotConvert as list

输出结果为:{"string"}


8.使用&连接string和list

使用&可以连接string和list变量,结果的类型由&运算符之前的变量类型决定,例如:

set stringBeforeAnd to "string"
set listBeforeAnd to {"list"}
set stringAndList to stringBeforeAnd & listBeforeAnd -- &之前的变量是一个string

输出结果为:"stringlist"


另一种情况:

-- string & list or list & string
set stringBeforeAnd to "string"
set listBeforeAnd to {"list"}
-- set stringAndList to stringBeforeAnd & listBeforeAnd -- 注释掉这段代码
set listAndString to listBeforeAnd & stringBeforeAnd -- &之前的变量是一个list

输出结果为:{"list", "string"}


这样的写法不够明确,将上面的代码改进如下:

-- A better way
set stringAndList to (listBeforeAnd as string) & stringBeforeAnd
set listAndString to (stringBeforeAnd as list) & listBeforeAnd

更好的做法是使用as关键字做出变量类型的显式声明。


9.使用itemized关键字

使用itemized关键字可以将一个string对象分割成单个的字符并组成一个新的列表,例如:

-- itemized string to character
set itemized to every character of stringAndString

输出结果为:{"H", "e", "l", "l", "o", " ", "A", "p", "p", "l", "e", "S", "c", "r", "i", "p", "t"}


10.分割和恢复字符串

可以将string分割为一个list。

首先通过AppleScript‘s text item delimiters来指定分割符号,然后通过every text item of来实现分割。方法如下:

-- AppleScript‘s text item delimiters
set defaultDelimiters to AppleScript‘s text item delimiters
--set AppleScript‘s text item delimiters to ""
set AppleScript‘s text item delimiters to " "
set listAfterDelimiter to every text item of stringAndString
set AppleScript‘s text item delimiters to defaultDelimiters
get listAfterDelimiter

注意要首先保存AppleScript‘s text item delimiters,在分割字符串完成后记得要将其还原。

使用" "分割字符串结果为:{"Hello", "AppleScript"}

使用""分割字符串结果为:{"H", "e", "l", "l", "o", " ", "A", "p", "p", "l", "e", "S", "c", "r", "i", "p", "t"}


可以将分割后的list恢复为一个string。恢复过程是一个逆向的过程,方法如下:

-- Restore list after delimiter to string
set defaultDelimiters to AppleScript‘s text item delimiters
set AppleScript‘s text item delimiters to " "
set restoredString to listAfterDelimiter as string
set AppleScript‘s text item delimiters to defaultDelimiters
get restoredString

这里也要保存和还原AppleScript‘s text item delimiters。


11.回到dialog

说了那么多list的特性,下面回到dialog的相关知识。

使用list可以指定dialog的按钮列表,例如:

-- list and dialog
display dialog stringAndString buttons {"OK"}
set buttonsList to {"That‘s awesome", "OK", "Cancel"}
set defaultButton to "That‘s awesome"
display dialog stringAndString buttons buttonsList default button defaultButton
display dialog stringAndString buttons buttonsList default button 2

display dialog后的字符串指定对话框的提示文字。

buttons后的列表为按钮列表。

default button后的字符串指定对话框弹出后的默认按钮名称,这可以使得你的程序更加的友好(按return就可以让对话框消失了):

AppleScript学习笔记(二)AppleScript的四种数据类型




Record(记录)

record类似于OC中的字典,其格式类似于:{name1:value1, name2:value2, name3:value3},其中name相当于字典中的key,value相当于字典中的value。


1.使用set to语句赋值

可以用上面的格式创建一个record变量并进行赋值,例如:

set aRecord to {name1:100, name2:"This is a record"}


2.使用name获取value

可以通过name获取record中对应的value,类似于objectForKey:方法,例如:

set tempValOfName to the name1 of aRecord

也可以利用name/value对来新建一个Record,例如:

set newerRecord to {name1:name1 of aRecord}


3.获取Record的name/value对数目

注意,record中的组成是属性(property)而不是元素(item),不要用item关键词来获取record中的属性。

获取record中的属性数目方法也是用count,例如:

set numberOfProperties to the count of aRecord


4.Record与Dialog

在点击了Dialog中的某个按钮让Dialog消失后,Dialog将返回一个Record变量给程序,我们可以用button returned这个name去获取对应的value从而知道用户刚刚按下了哪个按钮,并将其反馈出来,例如:

set stringOfDialog to "What is record?"
set returnRecord to display dialog stringOfDialog buttons {"I know", "do not know", "guessing"} default button 1
set buttonPressed to button returned of returnRecord
display dialog "Now you know it, right? " & buttonPressed

运行结果为:

AppleScript学习笔记(二)AppleScript的四种数据类型


在点击I know按钮后,程序将呼出一个新的对话框,上面显示了我们刚刚按下的按钮名称:

AppleScript学习笔记(二)AppleScript的四种数据类型


5.Record与Input text field

在对话框中我们可以通过适当的设计让它变成一个文本输入框,只需要一个default answer,例如:

-- input text field
set something to display dialog "Say something here, please" default answer ""
set textReturned to text returned of something

文本输入框返回的也是一个record变量,我们可以通过name(text returned)来获取用户输入的文字。

运行结果:

AppleScript学习笔记(二)AppleScript的四种数据类型

结果输出为:"100"


如果去掉下面的一行set,那么结果输出为:{button returned:"",text returned:"100"}


既然有了文本输入框,我们当然想用它来收集用户的意见,甚至对返回的文字做运算,例如:

-- input number
set recordReturned to display dialog "1 hour = ? min" default answer ""
set numberReturned to text returned of recordReturned
set theSeconds to numberReturned * 60
display dialog "1 hour = " & theSeconds & " seconds"

在计算时脚本程序可以将字符串numberReturned隐式地转换为number,但是如果用户输入的是字母、符号等的话程序就会出错。

好的编程习惯是我们必须在这里将numberReturned显式地转换为number,在上面代码第二行下面加入这一句:

set numberReturned to numberReturned as number




set to和copy

和OC类似,AppleScript中也存在copy关键字。

使用set to对number的赋值不会影响到其他变量,例如:

-- assign number
set initialValue to 80
set assignValue to initialValue
set initialValue to 75
get assignValue
-- get initialValue

输出结果中assignValue = 80,initialValue = 75,可以看到对initialValue的更改将不会影响到assignValue。

string同理。


number和string本身是不可变的,但是list和record本身的元素或属性的值是可以改变的,这又带来了区别。

执行下面这段脚本:

-- assing list
set initialList to {1, 2, 3}
set assignList to initialList
set initialList to {4, 5, 6}
-- set item 2 of initialList to 20
get assignList
get initialList

可以看到assignList = {1, 2, 3},initialList = {4, 5, 6}


将list中的第二个元素值改变,脚本如下:

-- assing list
set initialList to {1, 2, 3}
set assignList to initialList
-- set initialList to {4, 5, 6}
set item 2 of initialList to 20
get assignList
get initialList

可以看到assignList = initialList = {1, 20, 3}


如果我们要确保改变initialList的列表内容时,assignList的值不变,就要使用copy关键字,例如:

-- copy list
set initialList to {1, 2, 3}
copy initialList to copyList
set item 2 of initialList to 20
get copyList
get initialList

可以看到assignList = {1, 2, 3},initialList = {1, 20, 3}

综上,AppleScript中也有深复制和浅复制之分,但是我对脚本的底层实现并不了解,所以在此无法做进一步的解释。


record同理,可以执行下面的脚本看看:

-- assign record
set initialRecord to {name1:100}
set assignRecord to initialRecord
set initialRecord to {name2:200}
-- set name1 of initialRecord to 200
get assignRecord
get initialRecord

-- copy record
set initialRecord to {name1:100}
copy initialRecord to copyRecord
set name1 of initialRecord to 200
get copyRecord




注释

最后补充一下AppleScript的注释形式,有两种:“ -- ”和“ (* *) ”,第一种类似于OC中的“ // ”,第二种类似于OC中的“ /* */ ”。

例如:

-- comments
(*
Make your comments
And it can be multiline text.
Awesome, right?
*)

编译后注释会变成黑色。


当然你也可以用AppleScriptEditor的上下文菜单将一段文字快速变为注释:

先选择该段文字,然后右击呼出上下文菜单,选择Comment Tags:

AppleScript学习笔记(二)AppleScript的四种数据类型


要将一段由(**)注释掉的文字恢复成脚本,可以使用同样的方法还原。(该方法不能用于“ -- ”标记的注释)




小结

本文内容很长,讲了比较多的语法,比较无聊,希望AS4AS后面内容的趣味会增加。

先总结到这里了,等学习了新的内容会继续更新博客。


更多详细内容请参考《AppleScript for Absolute Starters》一书(中文名为《苹果脚本跟我学》)。



AppleScript学习笔记(二)AppleScript的四种数据类型

上一篇:Android Lint Problem


下一篇:Android开发之异常处理篇(一):SDK Manager闪退的解决方法