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

简介

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

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

Number(数字)

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

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

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

 
  1. -- set number and calculate

  2. set x to 10

  3. set y to 10

  4. set xy to x * y

  5. set x3 to y ^ 3


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

String(字符串)

1.使用set to语句赋值

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

 
  1. -- set string

  2. set emptyString to ""

  3. set aSpaceString to " "

  4. set helloString to "Hello"

  5. set AppleScriptString to "AppleScript"

2.使用&运算符连接

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

 
  1. -- string & string

  2. set stringAndString to helloString & aSpaceString & AppleScriptString


其输出结果为:

"Hello AppleScript"

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

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

 
  1. -- \"

  2. set exampleString to "\"Excuse me\""

  3. display dialog exampleString


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

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

 
  1. -- \\

  2. display dialog "blah blah \\\" blah"


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

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

 
  1. -- length of string

  2. set lengthOfString to the length of stringAndString

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

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

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

 
  1. set numberToString to 100 as string

  2. set stringToNumber to "10" as number

Dialog(对话框)

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

dialog的调用格式为:

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


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

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

 
  1. -- display dialog

  2. display dialog "Welcome to AppleScript"

  3. display dialog helloString

  4. display dialog stringAndString


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

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

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

{button returned:"好"}


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

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

List(列表)

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

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

1.使用set to语句赋值

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

  2. 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.使用&连接列表

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

 
  1. -- list and list

  2. set addToBeginList to {1}

  3. set addToEndList to {6}

  4. set currentList to {2, 3, 4, 5}

  5. set modifiedList to addToBeginList & currentList & addToEndList


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

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

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

 
  1. set item 2 of modifiedList to "2"

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

  3. 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来获取最后一个元素,负数表示从列表尾端开始获取元素,例如:

 
  1. set aList to {"hello", "hi"}

  2. 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中的子列表,例如:

 
  1. set longList to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

  2. 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关键字均可,例如:

 
  1. set listLength to the length of longList

  2. set listCount to the count of shortList

结果为10和5。

6.添加元素到列表末尾

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

 
  1. -- Add item to end of list

  2. set listNotAdded to {1, 2, 3, 4}

  3. set the end of listNotAdded to 5

  4. set the end of listNotAdded to {6, 7, 8, 9, 10}

  5. get listNotAdded


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

7.将string转换为list

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

 
  1. -- string to list

  2. set stringNotConvert to "string"

  3. set convertStringToList to stringNotConvert as list


输出结果为:{"string"}

8.使用&连接string和list

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

 
  1. set stringBeforeAnd to "string"

  2. set listBeforeAnd to {"list"}

  3. set stringAndList to stringBeforeAnd & listBeforeAnd -- &之前的变量是一个string


输出结果为:"stringlist"

另一种情况:

 
  1. -- string & list or list & string

  2. set stringBeforeAnd to "string"

  3. set listBeforeAnd to {"list"}

  4. -- set stringAndList to stringBeforeAnd & listBeforeAnd -- 注释掉这段代码

  5. set listAndString to listBeforeAnd & stringBeforeAnd -- &之前的变量是一个list


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

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

 
  1. -- A better way

  2. set stringAndList to (listBeforeAnd as string) & stringBeforeAnd

  3. set listAndString to (stringBeforeAnd as list) & listBeforeAnd

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

9.使用itemized关键字

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

 
  1. -- itemized string to character

  2. 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来实现分割。方法如下:

 
  1. -- AppleScript's text item delimiters

  2. set defaultDelimiters to AppleScript's text item delimiters

  3. --set AppleScript's text item delimiters to ""

  4. set AppleScript's text item delimiters to " "

  5. set listAfterDelimiter to every text item of stringAndString

  6. set AppleScript's text item delimiters to defaultDelimiters

  7. 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。恢复过程是一个逆向的过程,方法如下:

 
  1. -- Restore list after delimiter to string

  2. set defaultDelimiters to AppleScript's text item delimiters

  3. set AppleScript's text item delimiters to " "

  4. set restoredString to listAfterDelimiter as string

  5. set AppleScript's text item delimiters to defaultDelimiters

  6. get restoredString


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

11.回到dialog

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

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

 
  1. -- list and dialog

  2. display dialog stringAndString buttons {"OK"}

  3. set buttonsList to {"That's awesome", "OK", "Cancel"}

  4. set defaultButton to "That's awesome"

  5. display dialog stringAndString buttons buttonsList default button defaultButton

  6. display dialog stringAndString buttons buttonsList default button 2


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

buttons后的列表为按钮列表。

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

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从而知道用户刚刚按下了哪个按钮,并将其反馈出来,例如:

 
  1. set stringOfDialog to "What is record?"

  2. set returnRecord to display dialog stringOfDialog buttons {"I know", "do not know", "guessing"} default button 1

  3. set buttonPressed to button returned of returnRecord

  4. display dialog "Now you know it, right? " & buttonPressed


运行结果为:

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

5.Record与Input text field

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

 
  1. -- input text field

  2. set something to display dialog "Say something here, please" default answer ""

  3. set textReturned to text returned of something


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

运行结果:

结果输出为:"100"

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

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

 
  1. -- input number

  2. set recordReturned to display dialog "1 hour = ? min" default answer ""

  3. set numberReturned to text returned of recordReturned

  4. set theSeconds to numberReturned * 60

  5. 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的赋值不会影响到其他变量,例如:

 
  1. -- assign number

  2. set initialValue to 80

  3. set assignValue to initialValue

  4. set initialValue to 75

  5. get assignValue

  6. -- get initialValue


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

string同理。

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

执行下面这段脚本:

 
  1. -- assing list

  2. set initialList to {1, 2, 3}

  3. set assignList to initialList

  4. set initialList to {4, 5, 6}

  5. -- set item 2 of initialList to 20

  6. get assignList

  7. get initialList


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

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

 
  1. -- assing list

  2. set initialList to {1, 2, 3}

  3. set assignList to initialList

  4. -- set initialList to {4, 5, 6}

  5. set item 2 of initialList to 20

  6. get assignList

  7. get initialList


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

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

 
  1. -- copy list

  2. set initialList to {1, 2, 3}

  3. copy initialList to copyList

  4. set item 2 of initialList to 20

  5. get copyList

  6. get initialList


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

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

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

 
  1. -- assign record

  2. set initialRecord to {name1:100}

  3. set assignRecord to initialRecord

  4. set initialRecord to {name2:200}

  5. -- set name1 of initialRecord to 200

  6. get assignRecord

  7. get initialRecord

  8.  
  9. -- copy record

  10. set initialRecord to {name1:100}

  11. copy initialRecord to copyRecord

  12. set name1 of initialRecord to 200

  13. get copyRecord

注释

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

例如:

 
  1. -- comments

  2. (*

  3. Make your comments

  4. And it can be multiline text.

  5. Awesome, right?

  6. *)

编译后注释会变成黑色。

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

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

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

小结

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

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

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

猜你喜欢

转载自blog.csdn.net/mp624183768/article/details/81281940