学习Swift笔记 (十四)Swift的附属脚本(下标)

类和结构和枚举类型都可以通过定义下标来访问一组或者一个序列中的成员元素。通过下标索引就可以方便地检索和设置相应的值,而不需要其他的额外操作。比如你可以通过someArray[index]来访问数组中的元素,或者someDictionary[key]来对字典进行索引。

你可以为一个类型定义多个下标,以及适当的下标重载用来根据传递给下标的索引来设置相应地值。下标不仅可以定义为一维的,还可以根据需求定义为多维的,多个参数的。


1.下标语法

下标可以让你通过实例名后加中括号内一个或多个数值的形式检索一个元素。语法和方法语法和属性语法类似,通过使用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会被提供给setter。

和计算属性一样,只读下标可以不需要get关键词:

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

下面是一个只读下标的实现,定义了一个TimesTable结构来表示一个整数的倍数表:

struct TimesTable {
    let multiplier: Int
    subscript(index: Int) ->Int{
        return multiplier * index
    }
}

let threeTimesTable = TimesTable(multiplier: 3)
println("six times three is \(threeTimesTable[6])")
//six times three is 18
在这个例子里,实例TimesTable被创建为3倍数表,这是通过在初始化的时候为multiplier参数传入的数值3设置的。

注意:倍数表是根据特定的数学规则设置的,所以不应该为threeTimeTable[someIndex]元素设置一个新值,所以TimesTable的下标定义为只读。


2.下标的使用

下标的具体含义由使用它时的上下文来确定。下标主要用来作为集合,列表和序列的元素快捷方式。你可自由的为你的类或者结构定义你所需要的下标。

比如说,Swift中字典类型实现的下标是设置和检索字典实例中的值。可以通过分别给出下标中的关键词和值来设置多个值,也可以通过下标来设置单个字典的值:

var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
上面的例子中定义了一个变量numberOfLegs,然后通过i初始化。numberOfLegs的类型是字典类型Dictionary<String,Int>.在字典创建之后,例子使用了下标赋值方法添加了一个类型为字符串的键“bird”和int值2到字典中。

注意:Swift中字典类型实现的键值对下标是可选类型,对于numberOfLegs字典来说,返回的值是Int?,也就是可选Int值。字典的这种可选类型下标的方式说明不是所有的键都有对应的值。同样也可以通过给键赋值nil来删除这个键。


3.下标选项

下标可以接受任意数量的参数,参数的类型也可以各异。下标还可以返回任何类型的值。下标可以使用变量参数或者可变参数,但是不能够使用输入参数或者提供默认参数的值。

类或者结构可以根据需要实现各种下标方式,可以在需要的时候使用合适的下标通过中括号中的参数返回需要的值。这种多下标的定义被称作下标重载。

当然,最常见的下标用法是单个参数,可可以定义多个参数的下标。下面的例子演示了一个矩阵Matrix结构,它含有二维Double值。矩阵结构的下标包括两个整形参数:

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

矩阵Matrix提供了一个初始化方法,使用两个参数rows和columns,然后建立了一个数组来存储类型为Double的值rows*columns。每个矩阵中的位置都被设置了一个初始值0.0。通过传递初始值0.0和数组长度给数组初始化方法完成上述操作。

你可以两个参数row和column来完成Matrix的初始化:

var matrix = Matrix(rows: 2, columns: 2)
上面的初始化操作创建了一个两行两列的矩阵Matrix实例。这个矩阵实例的grid数组看起来是平坦的,但是实际上矩阵从上左到右下的一维存储形式。

Swift编程语言中文教程(十二):Swift的附属脚本(下标)

矩阵中的值可以通过使用包含row和column以及逗号的下标来设置:

1
2
matrix[ 0 , 1 = 1.5
matrix[ 1 , 0 = 3.2

这两个语句调用了下标的setter方法为右上和左下角的两个元素分别赋值1.5和3.2

Swift编程语言中文教程(十二):Swift的附属脚本(下标)

矩阵下标的getter和setter方法都包括了一个断言语句来检查下标row和column是否有效。通过indexIsValid方法来判断row和column是否在矩阵的范围内:

1
2
3
unc indexIsValidForRow ( row : Int , column : Int ) - > Bool  {
     return row  > = 0 & & row  < rows  & & column > = 0 & & column < columns
}

如果访问的矩阵越界的时候,断言就会被触发:

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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值