十.方法(续)
11.值类型可变的方法:默认情况下,结构体和枚举的实例方法不能改变该实例的存储属性。如果像让值类型的实例方法改变该实例的存储属性,程序需要用mutating将方法声明为可变方法。
12.可变方法甚至可以在方法体内对隐式的self重新赋值,这会使得新赋值的实例将在方法结束后替换原有的实例。
13.举个栗子:
struct test
{
var x : Int
var y : Int
mutating func kebian(x : Int, y : Int)
{
self.x += x
self.y += y
}
}
14.注意:常量类型的结构体、枚举是不可变的,因此不要对常量类型的结构体、枚举调用可变方法,否则将会导致编译错误。也不要在可变方法内改变结构体的常量属性。
15.可变方法改变self的栗子:
enum Planet : Int
{
case Mercury = 0, Venus, Earth, Mars, Jupiter, saturn, Uranus, Nepturn
mutating func next()
{
if self.rawValue < 8 && self.rawValue > -1
{
self = Planet(rawValue : self.rawValue + 1)!
}
}
mutating func prev()
{
if self.rawValue < 8 && self.rawValue > -1
{
self = Planet(rawValue: self.rawValue - 1)!
}
}
}
var pt = Planet.Venus
pt.next()//pt变成.Earth
pt.next()//pt变成.Mars
pt.prev()//pt变成.Earth
16.如果程序使用函数类型定义存储类型,并将函数或闭包作为该属性的初始值,那么这个属性就成了方法
17.换个角度来看,方法相当于一种一let声明的、类型为函数类型的存储属性。如果程序使用var声明存储属性,并将函数或闭包作为该属性的初始值,这样也可以定义方法,而且这样定义的方法比原来类型中的方法更加灵活:因为该方法的本质是var声明的变量存储属性,因此程序可以随时改变方法的实现体。
18.下面程序示范了以存储属性的方式来定义函数
//定义一个计算阶乘的全局函数
func factorial(n : Int) -> Int
{
var result = 1
for index 1...n
{
result *= index
}
}
struct SomeStruct
{
//将一个闭包作为info存储属性的初始值
var info: () -> void = {
print("info method...")
}
//将factorial全局函数作为fact存储属性的初始值
static var fact: (Int) -> Int = factorial
}
var sc = SomeStruct()
//调用info方法
sc.info()
//使用闭包对sc对象的info赋值,相当于重新定义sc的info方法
sc.info = {
print("reset info")
print("another method")
}
//再次调用info方法
sc.info()
var n = 6;
//调用fact方法,执行的是阶乘
SomeStruct.fact(6)
//使用闭包对SomeStruct的fact赋值,将阶乘重新定义为累加
SomeStruct.fact = {
var result = 1;
for index 1...$0{
result += index
}
return result
}
网友评论