微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

苹果新的编程语言 Swift 语言进阶九--方法和下标

? 一、方法?

? ??方法是与特定类型相关的函数。与属性一样,方法包括实例方法和类型方法

?? ? 类、结构、枚举都能定义实例方法。用来封装或实现给定类型的一个实例相关的功能或特定任务。

?? ? 类、结构、枚举也能定义与类型本身相关的类型方法。类型方法与Objective-C语言中的类方法相似。类型方法仅仅能在类型本身上调用

1.1 实例方法的定义

? ? ?实例方法是属于特定类、结构、枚举的实例的函数,它们用来支持那些实例的功能:提供存取和改动实例属性的方式。或者是提供与实例的功能相关的功能

? ? ?实例方法定义採用与函数同样的语法。实例方法一个类型定义内部定义和实现一个属于它的实例方法一个实例方法能够存取该类型的全部其他实例方法属性,而且一个实例方法仅能在它属于的特定类型的实例上被调用,不能脱离实例被调用。如:

class?Counter?{

? ?var?count?=0

? ?func?increment() {

? ? ? ?count++

? ? }

?

?

}

?? 该样例在类Counter内部定义了一个实例方法increment。

?? 并用以下方式调用该实例方法

let?counter?=Counter()

// the initial counter value is 0

counter.increment // the counter‘s value is Now 1

?? 与函数同样。方法的參数也能够有一个本地參数和一个外部參数。

?? 因为Swift对方法的命名採用和Objective-C相似的规则:方法的名字使用介词with、for或者by来标准引用它的第一个參数。

因此认情况,Swift给方法的第一个參数仅仅提供一个本地參数名,而不提供外部參数名。给其他參数则提供本地參数名和外部參数名。这样能够使方法的可读性更强。并能以自然和生动的方式调用方法

如:

count:Int?=0

? ?func?incrementBy(amount:Int,numberOfTimes) {

? ? ? ?count?+=amount?*numberOfTimes

? ? }

}

?? ?Counter的实例方法incrementBy带有两个參数amount和numberOfTimes,认情况下,amount仅作为本地參数名使用,而numberOfTimes作为本地和外部名使用。因此须要这样调用方法

let counter = Counter()

counter.incrementBy(5,numberOfTimes: 3)

?? ? 有时为方法的第一个參数提供一个外部參数名使实用的,因此你能够明白的为其加入一个外部參数名,或者使用#前缀来使其本地參数名与外部參数名一样。

?? ? 相反,假设你不想为方法的额外的參数提供一个外部參数名,能够使用(_)符号来明白。

? 1.2? 实例方法的变异

? ? ?认情况不能在一个类型为值类型(如结构和枚举)的实例方法内部改动它的属性

但能够通过在该类型的实例方法前面放置一个mutatingkeyword来同意该方法改动其属性,这称为方法的变异。例如以下所看到的:

struct?Pointx?=0.0,y?=0.0

mutating?func?moveByX(deltaXDoubleydeltaY) {

? ? ? ?x?+=deltaX

? ? ? ?y?+=deltaY

? ? }

}

var?somePoint?=Point(x:1.0y)

somePoint.moveByX(2.03.0 println("The point is Now at (\(somePoint.x),.y)")

// prints "The point is Now at (3.0,4.0)"

? ? 须要注意的是不能在一个实例常量上调用变异的方法

?? ??let?fixedPoint = Point(x:3.0,y:3.0)

? ? ?fixedPoint)

? ? ?// 将报一个执行时错误

? ?变异方法还能同意分配一个全然新的实例给隐含的self属性。例如以下所看到的:

? struct) {

? ? ? ?self?=Point(x:x?+deltaX,135);">y:y?+deltaY)

? ? }

?}

? ? 该样例在变异方法moveByX内创建了该实例的一个新的实例。

? 1.3 类型方法

? ? 为结构、枚举、类定义类型方法的语法例如以下:

? ??struct?SomeStruct?{

? ? ? ?static?func?someTypeMethod() {

? ? // type method implementation goes here


?? ? }

?? }

? ?class?SomeClass {

? ? ??class?fund?someTypeMethod() {

? ? ? ?// type method implementation goes here

? ? ? }

? ?}

? ? 为枚举和结构定义类型方法是在方法的funckeyword前面加入一个statickeyword来指示该方法是类型方法。为类定义类型方法是在所定义方法的funckeyword前面加入一个classkeyword来指示其是类型方法

? ? 类型方法的作用域是其支持的类型。

? ? 与属性同样。类型方法调用也使用点语法在所支持类型上调用

?SomeClass.someTypeMethod()

? ? 在类型方法方法体内。隐含的self属性引用的是类型本身。因此在类型方法方法体内使用到的不论什么方法属性引用的是其他类型级别的方法属性,即引用的是其他类型方法和静态属性

二、下标方法??

? ? ?? ? 类、结构和枚举都能定义下标方法,用来快捷存取一个集合、列表、或序列的成员。

? ? ? ? 通过为某个类型定义下标方法。就能够使用索引来设置和获取类型实例包括的成员值。如数组和词典类型都提供了下标方法,因此能够使用索引来存取一个数组或词典的值。

2.1? 下标方法定义

?? ? ? 下标方法的定义语法与实例方法和计算属性的语法相似。

?? ? ? 下标方法使用subscriptkeyword来指示是一个下标方法。与实例方法一样。下标方法定义中能够规定一个或多个输入參数。并带有一个返回类型。与实例方法不同的是下标方法能够是可读写的或是仅仅读的。与计算属性的定义一样。下标方法通过使用getter和setter来传达下标方法的行为。假设在下标方法的定义中getter和setter都被指定,则定义了一个可读写的下标方法,假设下标方法的定义中不包括setter。则定义了一个仅仅读的下标方法,而且这时代表getter方法的keywordget也能够省略。下标方法定义的完整语法例如以下:

subscript(index:Int) ->Int {

? ?get {

? ? ? ?// return an appropriate subscript value here

? ? }

? ?set(newValue) {

? ? ? ?// perform a suitable setting action here

? ? }

}

?? ? 该例定义了一个可读写的下标方法,newValue能够指定。也能够不指定。不指定时使用认的參数名newValue。

?? ? 例如以下样例展示了一个仅仅读下标方法的定义和使用。

因为仅仅读下标方法仅仅指定一个getter。意义是明白的。因此能够省略getkeyword。

struct 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”

?? 2.2 下标方法的使用?

? ? ? ? 你能为一个类型定义和实现多个下标方法。编译器基于你传送给下标方法的索引參数的类型来判断和选择适当的下标方法

? ? ? ? 与方法相似。下标方法能够包括随意数量的输入參数,且这些输入參数的类型能够是不论什么类型,下标方法也能返回不论什么类型。

下标方法也能使用可变參数,但不能使用in-out參数也不能通过认參数值。

? ? ? ? ? ? ? ? ? 如能够定义一个带有多个输入參数的表示多纬度的下标方法,以下的样例展示了怎样为一个矩阵结构定义一个带两个整数类型的下标方法以及怎样使用。定义的下标方法用来索引矩阵中定义的两纬度的元素。

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)

? ? }

?subscript(row:Int,column:Int) ->Double {

? ? ? ?get {

? ? ? ? ?

? ? ? ? ? ?return?grid[(row *columns) +column]

? ? ? ? }

? ? ? ?set {

? ? ? ?

? ? ? ? ? ?grid[(row *columns) +column] =newValue

? ? ? ? }

? ? }

}

? ? ?

?var?matrix =Matrix(rows:2,columns:2)

matrix[0,1] =1.5

matrix[1,0] =3.2


? ? ? ? ? ? ? ??版权全部。转载时请清楚注明链接和出处,谢谢!


? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐