下标

类、结构体和枚举可以使用下标,用来方便访问一个集合、列表或序列的成员。可以使用下标根据索引设置和获取值,而不需要单独的方法。举例来说,你可以使用someArray[index]来访问一个数组的实例中的元素,也可以使用someDictionary[key]来访问一个字典中的元素。

可以定义单一类型的多个脚本,根据你传递给脚本的索引值的类型会自动选择合适的重载脚本。脚本并不限制只能有一维,可以多个参数,以适应定制的需要。

下标语法

下标可以做到:实例名称之后的方括号中写一个或多个值来查询类型实例。它的语法类型实例方法语法和计算属性语法。使用subscript关键字定义下标,然后指定一个或多余一个的参数和返回类型,就像实例方法一样。不同于实例方法,下标可以是可读写的也可以是只读的。就像计算属性一样,这种限制是通过getter和setter实现的:

subscript​(​index​: ​Int​) -> ​Int​ {
​ ​get​ {
​ ​// return an appropriate subscript value here
​ }
​ ​set​(​newValue​) {
​ ​// perform a suitable setting action here
​ }
​}

newValue 的类型和下标返回值的类型相同。和计算属性一样,你可以选择不指定setter的参数((newValue))。没有指定参数的时候默认参数newValue生效。

和只读计算属性一样,可以把只读脚本中的get关键字丢掉:

subscript​(​index​: ​Int​) -> ​Int​ {
​ ​// return an appropriate subscript value here
​}

这里有一个只读下标的示例,它定义了一个叫做TimesTable的结构体表示一个整数的n倍数表:

truct​ ​TimesTable​ {
​ ​let​ ​multiplier​: ​Int
​ ​subscript​(​index​: ​Int​) -> ​Int​ {
​ ​return​ ​multiplier​ * ​index
​ }
​}
​let​ ​threeTimesTable​ = ​TimesTable​(​multiplier​: ​3​)
​println​(​"six times three is ​\(​threeTimesTable​[​6​])​"​)
​// prints "six times three is 18"

这个例子中,一个新的TimesTable实例被创建,用来表现一个整数的三倍数表。具体的,是通过传递一个3给结构体的初始化方法,初始化multiplier为3.

可以通过下标查询threeTimesTable实例,就像上面的threeTimesTable[6]。这个语句请求了three-times-table中的第六个元素,返回了18,也就是6的3倍。

NOTE

一个n倍数表依据的是数学规则。不会给threeTimesTable[someIndex]赋予一个新值,所以TimesTable的这个下标是一个只读下标。

下标用法

下标准确意义要依赖其使用的上下文。下标的典型用法是简洁的访问集合、列表或者序列的成员。也可以为了类或者结构体的特殊功能,用适当的方式实现下标。

举例来说,Swift的字典类型实现了一个下标来实现对字典类型实例中的值的读取和赋值。你可以在方括号中提供一个字典键值来设置一个字典内容,也可以将字典值赋给下标:

​var​ ​numberOfLegs​ = [​"spider"​: ​8​,​"ant"​: ​6​,​"cat"​: ​4​]
​numberOfLegs​[​"bird"​] = ​2

上面定义了一个变量叫做numberOfLegs,然后使用了包含三个键值对的字典的字面语句对其初始化。字典numberOfLegs是一个[String:Int]类型的。创建完这个字典后,例子采用下标分配并添加了一个键为“bird”,值为整型2的内容。

更多的关于字典下标的内容,参见 Accessing and Modifying a Dictionary。

NOTE

Swift的字典类型实现了它的key-vlaue下标,通过下标得到一个可选类型。比如上面的numberOfLegs字典,它的下标返回一个类型是Int?(或者可选int)的值。字典类型使用可选类型下标来模仿不是所有的键都会有一个对应的值,提供了一种处理可能对应的键为nil的途径。

Subscript Options

下标可以使用人一个数量的参数,而且这些参数可以是任意类型的。下标可以返回任意类型。下标可以使用变量参数,也可以使用可变参数,但是不能使用in-out参数或者提供参数默认值。

一个类好哦这结构体可以有多个下标实现,只要有必要,会根据在方括号中的值类型选择合适的下标实现。这种多下标的情况叫做下标重载(subscript overloading)。

尽管多数下标采用单一参数,但是你也可以定义多个参数的。下面的例子定义了一个矩阵结构体,表示了一个二维Double矩阵。它的下标就采用了两个整型做参数:

struct​ ​Matrix​ {
​ ​let​ ​rows​: ​Int​,​columns​: ​Int
​ ​var​ ​grid​: [​Double​]
​ ​init​(​rows​: ​Int​,​columns​: ​Int​) {
​ ​self​.​rows​ = ​rows
​ ​self​.​columns​ = ​columns
​ ​grid​ = ​Array​(​count​: ​rows​ * ​columns​,​repeatedValue​: ​0.0​)
​ }
​ ​func​ ​indexIsValidForRow​(​row​: ​Int​,​column​: ​Int​) -> ​Bool​ {
​ ​return​ ​row​ >= ​0​ && ​row​ < ​rows​ && ​column​ >= ​0​ && ​column​ < ​columns
​ }
​ ​subscript​(​row​: ​Int​,​column​: ​Int​) -> ​Double​ {
​ ​get​ {
​ ​assert​(​indexIsValidForRow​(​row​,​column​: ​column​),​"Index out of range"​)
​ ​return​ ​grid​[(​row​ * ​columns​) + ​column​]
​ }
​ ​set​ {
​ ​assert​(​indexIsValidForRow​(​row​,​"Index out of range"​)
​ ​grid​[(​row​ * ​columns​) + ​column​] = ​newValue
​ }
​ }
​}

Matrix提供了带两个参数(rows 和columns)的构造方法,创建了一个足够容纳rows*columns个值的Double数组。其中的每个位置都被给另一个初始值0.0.为了达到这个目的,数组的大小和每个位置的初始值被作为初始化参数传递进来。关于初始化方法的更多信息,参见Creating and Initializing an Array。
可以根据行列的数目来创建一个新的Matrix实例:
​var​ ​matrix​ = ​Matrix​(​rows​: ​2​,​columns​: ​2​)

上面的例子创建了一个Matrix实例,它有两行两列。Matrix实例的grid数组是一个平的矩阵,读取它要从左上到右下:

传递行和列的值(用逗号分割他们)给下标,可以对矩阵中的值进行设置:

​matrix​[​0​,​1​] = ​1.5
​matrix​[​1​,​0​] = ​3.2

这两句调用了下标的setter给矩阵右上角的位置(row 是0,column是1)设置了值1.5,给左下角的位置(row是1,column是0)设置了值3.2:

Matrix下标的getter和setter都含有一个检查下标的row 和column是否合法的断言。为了支持这个断言,Matrix提供了一个方便调用的方法叫做indexIsValidForRow(_:column:),这个方法检查了请求的row和column是否在矩阵的范围内:

​func​ ​indexIsValidForRow​(​row​: ​Int​,​column​: ​Int​) -> ​Bool​ {
​    ​return​ ​row​ >= ​0​ && ​row​ < ​rows​ && ​column​ >= ​0​ && ​column​ < ​columns
​}

如果尝试访问超过矩阵范围的下标,断言就被触发:

​let​ ​someValue​ = ​matrix​[​2​,​2​]
​// this triggers an assert,because [2,2] is outside of the matrix bounds

[翻译]Swift编程语言——下标的更多相关文章

  1. ios – 声明NSDictionary并在Swift中添加键值对?

    我一直在尝试使用类类型键和值来声明一个NSDictionary,如下所示:这里,“Category”和“SubCategory”是全局类.我知道我不能将类类型用于关键字段.但是,无论如何,我应该做到这一点.有没有办法做到这一点?如何声明专门的NSDictionary或类似的东西来做到这一点?

  2. ios – Swift相当于`[NSDictionary initWithObjects:forKeys:]`

    Swift的原生字典是否与[NSDictionaryinitWithObjects:forKeys:]相当?假设我有两个带键和值的数组,并希望将它们放在字典中.在Objective-C中,我这样做:当然我可以通过两个数组迭代一个计数器,使用vardict:[String:Int]并逐步添加东西.但这似乎不是一个好的解决方案.使用zip和enumerate可能是同时迭代两者的更好方法.然而,这种方法

  3. ios – 在Swift中获取Cocoa Touch Framework项目版本字符串

    有谁知道这是否是我的项目设置中的缺陷,Xcode中的一个错误,或者是否有一种方法可以将Swift中的框架版本作为String或数组获取,这样我可以提供比major.minor更精细的版本控制?

  4. ios – 搜索数组swift中的对象

    我正在尝试使用UISearchController创建搜索功能.但是,我似乎无法使其与我的团队对象一起工作.我首先创建了一个包含id,name和shortname的TeamObject.然后我从一个url中检索teamData,并将TeamObjects添加到一个填充到tableView中的数组中.这个tableView包含一个searchController,它假设过滤数据,但没有任何反应.阵列

  5. ios – Swift可选项:语言问题,还是做错了什么?

    应该有可选的类型;type是但是,如果我这样做,它的工作原理:它似乎是基本的替代,但我可能会遗漏一些语言的细微差别.谁能对此有所了解?之后就像暧昧一样,更多,这是我的解决方案:这适用于所有非对象Swift对象,包括Swift字符串,数字等.感谢Viktor提醒我String不是Swift中的对象.如果您知道值的类型,您可以替换任何?使用适当的可选类型,如String?

  6. ios – Swift – 使用字典数组从字典访问数据时出错

    我有一个非常简单的例子,说明我想做什么基本上,我有一个字典,其值包含[String:String]字典数组.我把数据填入其中,但当我去访问数据时,我收到此错误:Cannotsubscriptavalueoftype‘[([String:String])]?’withanindexoftype‘Int’请让我知道我做错了什么.解决方法您的常量数组是可选的.订阅字典总是返回一个可选项.你必须打开它.更

  7. ios – 在Swift中使用“Map”创建两个数组的超集

    假设我有两个数组:我想组合两个数组,以便我得到一个输出我该怎么做呢?

  8. 模糊地使用’下标’ – ios 9 Swift 2.0

    我在xcode7.0上使用Swift2.0编写iosapp.在更新到最新版本的xCode7.1之前,完全相同的代码完全正常更新后,我收到此错误:Ambiguoususeof‘subscript’在这些方面:这是全班:Theoriginallibrary解决方法编译器不知道self.itemAttributes[indexPath.section]返回的内容,因为它定义为NSMutableArray

  9. xcode – Swift – 检索子视图

    解决方法UIViewController没有子视图属性.它有一个view属性,它有一个subviews属性:但通常这不是一个好主意.您应该将所需的标签放入IBOutletCollection并迭代它.否则,您与确切的子视图集密切相关.要创建IBOutletCollection,请在IB中选择所需的所有标签,然后将其控制拖动到源代码中.它应该询问您是否要创建一个集合数组.

  10. iOS Swift – 如何使用Core Data存储数组?

    我是iOS开发的新手,想要知道我应该指定哪种数据类型来存储多个字符串(数组).该应用程序与食物有关,我需要将多种成分存储为一个属性.我当时正在考虑将原料作为实体,但我只是想让原料变得容易.我已阅读有关可转换类型但人们似乎并不建议使用它来存储数组.解决方法警告:提前见解答.你没有.将数据存储在数组中并不会使您更容易.相反,它会让事情变得更加困难一小时.想象一下,你想要显示包含所选成分的所有食谱.对于

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部