The Swift Programming Language--语言指南--附属脚本

附属脚本可以定义在类(Class)、结构体(structure)和枚举(enumeration)这些目标中,可以认为是访问对象、集合或序列的快捷方式,不需要再调用实例的特定的赋值和访问方法。举例来说,用附属脚本访问一个数组(Array)实例中的元素可以这样写 someArray[index] ,访问字典(Dictionary)实例中的元素可以这样写 someDictionary[key]。
 
对于同一个目标可以定义多个附属脚本,通过索引值类型的不同来进行重载,而且索引值的个数可以是多个。
 
译者:这里附属脚本重载在本小节中原文并没有任何演示
 
附属脚本语法
附属脚本允许你通过在实例后面的方括号中传入一个或者多个的索引值来对实例进行访问和赋值。语法类似于实例方法和计算型属性的混合。与定义实例方法类似,定义附属脚本使用subscript关键字,显式声明入参(一个或多个)和返回类型。与实例方法不同的是附属脚本可以设定为读写或只读。这种方式又有点像计算型属性的getter和setter:
 
 
  1. subscript(index: Int) -> Int { 
  2.     get { 
  3.         // 返回与入参匹配的Int类型的值 
  4.     } 
  5.  
  6.     set(newValue) { 
  7.         // 执行赋值操作 
  8.     } 
newValue的类型必须和附属脚本定义的返回类型相同。与计算型属性相同的是set的入参声明newValue就算不写,在set代码块中依然可以使用默认的newValue这个变量来访问新赋的值。
 
与只读计算型属性一样,可以直接将原本应该写在get代码块中的代码写在subscript中:
 
 
  1. subscript(index: Int) -> Int { 
  2.     // 返回与入参匹配的Int类型的值 
下面代码演示了一个在TimesTable结构体中使用只读附属脚本的用法,该结构体用来展示传入整数的n倍。
 
 
  1. struct TimesTable { 
  2.     let multiplier: Int 
  3.     subscript(index: Int) -> Int { 
  4.         return multiplier * index 
  5.     } 
  6. let threeTimesTable = TimesTable(multiplier: 3) 
  7. println("3的6倍是\(threeTimesTable[6])"
  8. // 输出 "3的6倍是18" 
在上例中,通过TimesTable结构体创建了一个用来表示索引值三倍的实例。数值3作为结构体构造函数入参初始化实例成员multiplier。
 
你可以通过附属脚本来来得到结果,比如threeTimesTable[6]。这句话访问了threeTimesTable的第六个元素,返回18或者6的3倍。
 
注意:TimesTable例子是基于一个固定的数学公式。它并不适合开放写权限来对threeTimesTable[someIndex]进行赋值操作,这也是为什么附属脚本只定义为只读的原因。
 
附属脚本用法
根据使用场景不同附属脚本也具有不同的含义。通常附属脚本是用来访问集合(collection),列表(list)或序列(sequence)中元素的快捷方式。你可以在你自己特定的类或结构体中自由的实现附属脚本来提供合适的功能。
 
例如,Swift 的字典(Dictionary)实现了通过附属脚本来对其实例中存放的值进行存取操作。在附属脚本中使用和字典索引相同类型的值,并且把一个字典值类型的值赋值给这个附属脚本来为字典设值:
 
 
  1. var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4] 
  2. numberOfLegs["bird"] = 2 
上例定义一个名为numberOfLegs的变量并用一个字典字面量初始化出了包含三对键值的字典实例。numberOfLegs的字典存放值类型推断为Dictionary<String, Int>。字典实例创建完成之后通过附属脚本的方式将整型值2赋值到字典实例的索引为bird的位置中。
 
更多关于字典(Dictionary)附属脚本的信息请参考读取和修改字典
 
注意:Swift 中字典的附属脚本实现中,在get部分返回值是Int?,上例中的numberOfLegs字典通过下边返回的是一个Int?或者说“可选的int”,不是每个字典的索引都能得到一个整型值,对于没有设过值的索引的访问返回的结果就是nil;同样想要从字典实例中删除某个索引下的值也只需要给这个索引赋值为nil即可。
 
附属脚本选项
附属脚本允许任意数量的入参索引,并且每个入参类型也没有限制。附属脚本的返回值也可以是任何类型。附属脚本可以使用变量参数和可变参数,但使用写入读出(in-out)参数或给参数设置默认值都是不允许的。
 
一个类或结构体可以根据自身需要提供多个附属脚本实现,在定义附属脚本时通过入参个类型进行区分,使用附属脚本时会自动匹配合适的附属脚本实现运行,这就是附属脚本的重载。
 
一个附属脚本入参是最常见的情况,但只要有合适的场景也可以定义多个附属脚本入参。如下例定义了一个Matrix结构体,将呈现一个Double类型的二维矩阵。Matrix结构体的附属脚本需要两个整型参数:
 
 
  1. struct Matrix { 
  2.     let rows: Int, columns: Int 
  3.     var grid: [Double] 
  4.     init(rows: Int, columns: Int) { 
  5.         self.rows = rows 
  6.         self.columns = columns 
  7.         grid = Array(count: rows * columns, repeatedValue: 0.0) 
  8.     } 
  9.     func indexIsValidForRow(row: Int, column: Int) -> Bool { 
  10.         return row >= 0 && row < rows && column >= 0 && column < columns 
  11.     } 
  12.     subscript(row: Int, column: Int) -> Double { 
  13.         get { 
  14.             assert(indexIsValidForRow(row, column: column), "Index out of range"
  15.             return grid[(row * columns) + column] 
  16.         } 
  17.         set { 
  18.             assert(indexIsValidForRow(row, column: column), "Index out of range"
  19.             grid[(row * columns) + columns] = newValue 
  20.         } 
  21.     } 
Matrix提供了一个两个入参的构造方法,入参分别是rows和columns,创建了一个足够容纳rows * columns个数的Double类型数组。为了存储,将数组的大小和数组每个元素初始值0.0,都传入数组的构造方法中来创建一个正确大小的新数组。关于数组的构造方法和析构方法请参考创建并且构造一个数组。
 
你可以通过传入合适的row和column的数量来构造一个新的Matrix实例:
 
 
  1. var matrix = Matrix(rows: 2, columns: 2) 
上例中创建了一个新的两行两列的Matrix实例。在阅读顺序从左上到右下的Matrix实例中的数组实例grid是矩阵二维数组的扁平化存储:
 
 
  1. // 示意图 
  2. grid = [0.0, 0.0, 0.0, 0.0] 
  3.  
  4.         col0    col1 
  5. row0   [0.0,    0.0, 
  6. row1    0.0,    0.0] 
将值赋给带有row和column附属脚本的matrix实例表达式可以完成赋值操作,附属脚本入参使用逗号分割
 
 
  1. matrix[0, 1] = 1.5 
  2. matrix[1, 0] = 3.2 
上面两条语句分别让matrix的右上值为 1.5,坐下值为 3.2:
 
 
  1. [0.0, 1.5, 
  2.  3.2, 0.0] 
Matrix附属脚本的getter和setter中同时调用了附属脚本入参的row和column是否有效的判断。为了方便进行断言,Matrix包含了一个名为indexIsValid的成员方法,用来确认入参的row或column值是否会造成数组越界:
 
 
  1. func indexIsValidForRow(row: Int, column: Int) -> Bool { 
  2.     return row >= 0 && row < rows && column >= 0 && column < columns 
断言在附属脚本越界时触发:
 
 
  1. let someValue = matrix[2, 2] 
  2. // 断言将会触发,因为 [2, 2] 已经超过了matrix的最大长度 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值