swift入门11 下标脚本(subscript)
Classes, structures, and enumerations can define subscripts, which are shortcuts for accessing the member elements of a collection, list, or sequence. You use subscripts to set and retrieve values by index without needing separate methods for setting and retrieval. For example, you access elements in an Array instance as someArray[index] and elements in a Dictionary instance as someDictionary[key].
类,结构,枚举都可以定义下标脚本(subscripts),下标脚本是一种获取集合列表或序列的成员元素的快速方法。
使用下标脚本可以通过索引设置和获取值,而不需要设置和获取方法。比如,你可以用someArray[index]来获取一个数字的元素,用someDictionary[key]来获取一个字典的元素。
You can define multiple subscripts for a single type, and the appropriate subscript overload to use is selected based on the type of index value you pass to the subscript. Subscripts are not limited to a single dimension, and you can define subscripts with multiple input parameters to suit your custom type’s needs.
你可以给一个类型定义多个下标脚本,合适的下标脚本将会根据你传给下标脚本的值的类型而被选中执行。下标脚本不一定只是一维的,你可以给下标脚本定义多个输入参数,以匹配你的类型的需求。
下标脚本语法
Subscripts enable you to query instances of a type by writing one or more values in square brackets after the instance name. Their syntax is similar to both instance method syntax and computed property syntax. You write subscript definitions with the subscript keyword, and specify one or more input parameters and a return type, in the same way as instance methods. Unlike instance methods, subscripts can be read-write or read-only.
下标脚本使你可以查询一个类型的实例,只需要在实例名字后面的方括号里写上一个或多个值。这跟实例方法语法和计算属性语法相似。用subscript关键字引导下标脚本定义,然后指定一个或多个输入参数和一个返回值,跟实例方法一样。和实例方法不一样的是,下标脚本可以是可读写的或是只读的。
subscript(index: Int) -> Int {
get {
// 返回一个适当的下标脚本值
}
set(newValue) {
// 执行一些设置操作
}
}
The type of newValue is the same as the return value of the subscript. As with computed properties, you can choose not to specify the setter’s (newValue) parameter. A default parameter called newValue is provided to your setter if you do not provide one yourself.
newValue的类型和下标脚本的返回值的类型一样。至于计算属性,你可以选择不指定setter参数。如果你不提供你自己的setter参数,那么就会调用默认的参数—newValue。
As with read-only computed properties, you can simplify the declaration of a read-only subscript by removing the get keyword and its braces:
至于只读的计算属性的声明,只需把get关键字和括号去掉即可:
subscript(index: Int) -> Int {
// return an appropriate subscript value here
}
下面是一个只读下标脚本的实现的例子,
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")
// Prints "six times three is 18"
In this example, a new instance of TimesTable is created to represent the three-times-table. This is indicated by passing a value of 3 to the structure’s initializer as the value to use for the instance’s multiplier parameter.
这个例子中,创建了一个新的TimesTable实例,用来表示three-times-table。这是因为把3传递给了结构的初始化方法,3被当作了实例等multipiler参数的值。
You can query the threeTimesTable instance by calling its subscript, as shown in the call to threeTimesTable[6]. This requests the sixth entry in the three-times-table, which returns a value of 18, or 3 times 6.
你可以通过调用threeTimesTable的下标脚本来查询它的实例,比如示例中的threeTimesTable[6]。这个操作请求获取
three-times-table中的第六个实体,返回的值是18,即3乘6.
下标脚本的用法
The exact meaning of “subscript” depends on the context in which it is used. Subscripts are typically used as a shortcut for accessing the member elements in a collection, list, or sequence. You are free to implement subscripts in the most appropriate way for your particular class or structure’s functionality.
下标脚本的确切含义取决于它的上下文。下标脚本的典型用法是快速获取集合,列表或序列的成员元素。你可以在类或结构中用合适的方式实现自己的下标脚本。
For example, Swift’s Dictionary type implements a subscript to set and retrieve the values stored in a Dictionary instance. You can set a value in a dictionary by providing a key of the dictionary’s key type within subscript brackets, and assigning a value of the dictionary’s value type to the subscript:
比如,swift的字典类型实现了从字典实例中设置和获取值的下标脚本。你可以通过健来设置和赋予一个字典的值,
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
The example above defines a variable called numberOfLegs and initializes it with a dictionary literal containing three key-value pairs. The type of the numberOfLegs dictionary is inferred to be [String: Int]. After creating the dictionary, this example uses subscript assignment to add a String key of "bird" and an Int value of 2 to the dictionary.
上面的例子定义了一个变量numberOfLegs,并初始化为一个含有三个键值对的字典。numberOfLegs字典的类型为 [String: Int].创建了该字典后,这个例子使用下标脚本把一个键为bird,值为2的键值对添加到字典中。
下标脚本选择
Subscripts can take any number of input parameters, and these input parameters can be of any type. Subscripts can also return any type. Subscripts can use variadic parameters, but they can’t use in-out parameters or provide default parameter values.
下标脚本可以接收任意多个输入参数,这些输入参数可以是任意类型。下标脚本还能返回任意类型。下标脚本可以使用可变参数,但是不能有in-out参数或给参数设置默认值。
A class or structure can provide as many subscript implementations as it needs, and the appropriate subscript to be used will be inferred based on the types of the value or values that are contained within the subscript brackets at the point that the subscript is used. This definition of multiple subscripts is known as subscript overloading.
一个类或结构需要多少下标脚本实现就可以有多少下标脚本实现,相应的下标脚本会根据值的类型 或者下标脚本括号内包含的值 被使用,这称为下标脚本重载(subscript overloading).
While it is most common for a subscript to take a single parameter, you can also define a subscript with multiple parameters if it is appropriate for your type.
下标脚本接收一个参数是最常见的,但是你也可以定义一个接收多个参数的下标脚本。
struct Matrix {
let rows: Int, columns: Int
var grid: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(repeating: 0.0, count: rows * columns)
}
func indexIsValid(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row: Int, column: Int) -> Double {
get {
assert(indexIsValid(row: row, column: column), "Index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValid(row: row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
}
}
Matrix provides an initializer that takes two parameters called rows and columns, and creates an array that is large enough to store rows * columns values of type Double. Each position in the matrix is given an initial value of 0.0. To achieve this, the array’s size, and an initial cell value of 0.0, are passed to an array initializer that creates and initializes a new array of the correct size.
Matrix有一个初始化方法,接收两个参数,rows和columns,然后创建一个足够大的数组,存储rows*columns 的double类型的值。matrix中的每个点都有个初始值0.0。为了实现这个,把数组的大小,值为0.0的初始cell传递给一个数组初始化方法,该方法创建并初始化一个合适大小的新数组。
You can construct a new Matrix instance by passing an appropriate row and column count to its initializer:
你可以传给初始化方法和事的row和column值来构建一个新的Matrix实例。
var matrix = Matrix(rows: 2, columns: 2)
The preceding example creates a new Matrix instance with two rows and two columns. The grid array for this Matrix instance is effectively a flattened version of the matrix, as read from top left to bottom right:
上面的例子创建了一个两行两列的Matrix实例。这个Matrix实例的grid数组是一种matrix的高效的平面版本:
可以通过下标脚本来设置matrix的值
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
These two statements call the subscript’s setter to set a value of 1.5 in the top right position of the matrix (where row is 0 and column is 1), and 3.2 in the bottom left position (where row is 1 and column is 0):
这两条语句调用下标脚本的setter方法,把矩阵的右上位置(第0行,第1列)的值设为1.5,把左下位置(第1行,第0列)的值设为3.2.
The Matrix subscript’s getter and setter both contain an assertion to check that the subscript’s row and column values are valid. To assist with these assertions, Matrix includes a convenience method called indexIsValid(row:column:), which checks whether the requested row and column are inside the bounds of the matrix:
Matrix下标脚本的getter和setter都包含有检查此下巴的行与列的值是否有效的断言。为了联合使用这些断言,Matrix包含了一个便捷的方法indexIsValid(row:column:),该方法检查请求的行与列在矩阵的边界内:
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
An assertion is triggered if you try to access a subscript that is outside of the matrix bounds:
如果你试图获取的值超过了matrix的范围,就会出发一个断言(assertion):
let someValue = matrix[2, 2]
// 这会触发一个断言, 因为 [2, 2] 超出了matrix的范围
如果你觉得文章不错,可以给我打赏点比特股(bts),以示支持。_
BTS6jUaVVkz9gN8t9sWY9NR5UbiubSz7QtVDnEtFGpujYeqQSfQ5E