Swift—扩展声明-备
2016-05-03 11:04
381 查看
声明扩展的语法格式如下:
extension 类型名 {
//添加新功能
}
声明扩展的关键字是extension,“类型名”是Swift中已有的类型,包括类、结构体和枚举,但是我们仍然可以扩展整型、浮点型、布尔型、字符串等基本数据类型,这是因为这些类型本质上也是结构体类型。打开Int的定义如下:
struct Int : SignedInteger {
init()
init(_ value: Int)
static func convertFromIntegerLiteral(value: Int) -> Int
typealias ArrayBoundType = Int
func getArrayBoundValue() -> Int
static var max: Int { get }
static var min: Int { get }
}
从定义可见Int是结构体类型。不仅是Int类型,我们熟悉的整型、浮点型、布尔型、字符串等数据类型本质上都是结构体类型。
Swift中的扩展机制可以在原始类型中添加的新功能包括:
实例计算属性和类型计算属性
实例方法和类型方法
构造函数
下标
还有嵌套类型等内容也可以扩展,扩展还可以遵从协议。
===================================
可以在原始类型上扩展计算属性,包括实例计算属性和静态计算属性。添加计算属性的定义,与普通的计算属性的定义是一样的。
实例计算属性示例:在网络编程时,为了减少流量,从服务器端返回的不是信息描述,而是编码,然后在本地再将编码转换为描述信息。为此定义了如下Int类型扩展:
[html] view plain copy
print?
extension Int { //定义Int类型的扩展
var errorMessage : String { //只读计算属性
var errorStr = ""
switch (self) {
case -7:
errorStr = "没有数据。"
case -6:
errorStr = "日期没有输入。"
case -5:
errorStr = "内容没有输入。"
case -4:
errorStr = "ID没有输入。"
case -3:
errorStr = "据访问失败。"
case -2:
errorStr = "您的账号最多能插入10条数据。"
case -1:
errorStr = "用户不存在,请到http://51work6.com注册。"
default:
errorStr = ""
}
return errorStr
}
}
let message = (-7).errorMessage //获得-7编码对应的描述信息
print("Error Code : -7 , Error Message : \(message)")
注意整个-7包括负号是一个完整的实例,因此调用它的属性时需要将-7作为一个整体用小括号括起来。然而,如果是7则不需要括号。
下面再看一个静态属性的示例:
[html] view plain copy
print?
struct Account { //定义Account结构体
var amount : Double = 0.0 //账户金额
var owner : String = "" //账户名
}
extension Account { //定义Account结构体的扩展静态
static var interestRate : Double { //利率
return 0.0668
}
}
print(Account.interestRate) //打印输出interestRate属性
打印输出interestRate属性,访问方式与其他的静态计算属性一样,通过“类型名”加“.”来访问静态计算属性。
扩展方法
可以在原始类型上扩展方法,包括实例方法和静态方法。这些添加方法的定义与普通方法的定义是一样的。
下面先看一个示例:
[html] view plain copy
print?
extension Double {//定义Double类型的扩展
static var interestRate : Double = 0.0668 //利率
func interestBy1() -> Double {
return self * Double.interestRate //静态属性利率
}
mutating func interestBy2() { //定义实例方法interestBy2
self = self * Double.interestRate
}
static func interestBy3(amount : Double) -> Double { //定义静态方法interestBy3
return interestRate * amount //返回值是计算利息结果
}
}
let interest1 = (10_000.00).interestBy1() //调用interestBy1方法计算利息
print("利息1 : \(interest1)")
var interest2 = 10_000.00 //调用interestBy2方法计算利息
interest2.interestBy2()
print("利息2 : \(interest2)")
var interest3 = Double.interestBy3(10_000.00) //调用interestBy3方法计算利息
print("利息3 : \(interest3)")
代码self = self *Double.interestRate,把计算结果直接赋值给当前实例self。在结构体和枚举类型中给self赋值会有编译错误,需要在方法前面加上mutating关键字,表明这是变异方法。
调用interestBy1方法计算利息,调用它的实例10_000.00,它的返回值被赋值给interest1常量,这是很常见的调用过程。
调用interestBy2方法计算利息,我们不能使用10_000.00实例调用,而是需要一个Double类型的变量interest2。interestBy2是变异方法,它会直接改变变量interest2的值,因此interest2.interestBy2()语句调用完成后,变量interest2的值就改变了。
调用interestBy3方法计算利息,它是静态方法,调用它需要以“类型名.”的方式即“Double.”的方式调用。
=================================
扩展类型的时候,也可以添加新的构造函数。值类型与引用类型扩展有所区别。值类型包括了除类以外的其他类型,主要是枚举类型和结构体类型。
值类型扩展构造函数
扩展结构体类型中定义构造函数的示例:
[html] view plain copy
print?
struct Rectangle {
var width : Double
var height : Double
init(width : Double, height : Double) {
self.width = width
self.height = height
}
}
extension Rectangle { //定义了Rectangle的扩展类型
init(length : Double) {
self.init(width : length, height : length)
}
}
var rect = Rectangle(width : 320.0, height : 480.0) //调用两个参数的构造函数,这个构造函数是原始类型提供, Rectangle类型已经是扩展类型
print("长方形:\(rect.width) x \(rect.height)")
var square = Rectangle(length: 500.0) //调用一个参数的构造函数,这个构造函数是扩展类型提供的
print("正方形:\(square.width) x \(square.height)")
self.init是调用了原始类型的两个参数的构造函数。
引用类型扩展构造函数
扩展类中定义构造函数的示例:
[html] view plain copy
print?
class Person {
var name : String
var age : Int
func description() -> String {
return "\(name) 年龄是: \(age)"
}
init (name : String, age : Int) {
self.name = name
self.age = age
}
}
extension Person { //定义Person类的扩展类型
convenience init (name : String) { //便利构造函数
self.init(name : name, age : 8)
}
}
let p1 = Person(name : "Mary") //调用两个参数的构造函数,这个构造函数是原始类型提供,这时候的Person类型已经是扩展类型。
print("Person1 : \(p1.description())")
let p2 = Person(name : "Tony", age : 28)// 调用一个参数的构造函数创建Person实例,这个构造函数是扩展类型提供的。
print("Person2 : \(p2.description())")
代码self.init(name :name, age : 8)调用指定构造函数代理部分构造任务。
extension 类型名 {
//添加新功能
}
声明扩展的关键字是extension,“类型名”是Swift中已有的类型,包括类、结构体和枚举,但是我们仍然可以扩展整型、浮点型、布尔型、字符串等基本数据类型,这是因为这些类型本质上也是结构体类型。打开Int的定义如下:
struct Int : SignedInteger {
init()
init(_ value: Int)
static func convertFromIntegerLiteral(value: Int) -> Int
typealias ArrayBoundType = Int
func getArrayBoundValue() -> Int
static var max: Int { get }
static var min: Int { get }
}
从定义可见Int是结构体类型。不仅是Int类型,我们熟悉的整型、浮点型、布尔型、字符串等数据类型本质上都是结构体类型。
Swift中的扩展机制可以在原始类型中添加的新功能包括:
实例计算属性和类型计算属性
实例方法和类型方法
构造函数
下标
还有嵌套类型等内容也可以扩展,扩展还可以遵从协议。
===================================
可以在原始类型上扩展计算属性,包括实例计算属性和静态计算属性。添加计算属性的定义,与普通的计算属性的定义是一样的。
实例计算属性示例:在网络编程时,为了减少流量,从服务器端返回的不是信息描述,而是编码,然后在本地再将编码转换为描述信息。为此定义了如下Int类型扩展:
[html] view plain copy
print?
extension Int { //定义Int类型的扩展
var errorMessage : String { //只读计算属性
var errorStr = ""
switch (self) {
case -7:
errorStr = "没有数据。"
case -6:
errorStr = "日期没有输入。"
case -5:
errorStr = "内容没有输入。"
case -4:
errorStr = "ID没有输入。"
case -3:
errorStr = "据访问失败。"
case -2:
errorStr = "您的账号最多能插入10条数据。"
case -1:
errorStr = "用户不存在,请到http://51work6.com注册。"
default:
errorStr = ""
}
return errorStr
}
}
let message = (-7).errorMessage //获得-7编码对应的描述信息
print("Error Code : -7 , Error Message : \(message)")
注意整个-7包括负号是一个完整的实例,因此调用它的属性时需要将-7作为一个整体用小括号括起来。然而,如果是7则不需要括号。
下面再看一个静态属性的示例:
[html] view plain copy
print?
struct Account { //定义Account结构体
var amount : Double = 0.0 //账户金额
var owner : String = "" //账户名
}
extension Account { //定义Account结构体的扩展静态
static var interestRate : Double { //利率
return 0.0668
}
}
print(Account.interestRate) //打印输出interestRate属性
打印输出interestRate属性,访问方式与其他的静态计算属性一样,通过“类型名”加“.”来访问静态计算属性。
扩展方法
可以在原始类型上扩展方法,包括实例方法和静态方法。这些添加方法的定义与普通方法的定义是一样的。
下面先看一个示例:
[html] view plain copy
print?
extension Double {//定义Double类型的扩展
static var interestRate : Double = 0.0668 //利率
func interestBy1() -> Double {
return self * Double.interestRate //静态属性利率
}
mutating func interestBy2() { //定义实例方法interestBy2
self = self * Double.interestRate
}
static func interestBy3(amount : Double) -> Double { //定义静态方法interestBy3
return interestRate * amount //返回值是计算利息结果
}
}
let interest1 = (10_000.00).interestBy1() //调用interestBy1方法计算利息
print("利息1 : \(interest1)")
var interest2 = 10_000.00 //调用interestBy2方法计算利息
interest2.interestBy2()
print("利息2 : \(interest2)")
var interest3 = Double.interestBy3(10_000.00) //调用interestBy3方法计算利息
print("利息3 : \(interest3)")
代码self = self *Double.interestRate,把计算结果直接赋值给当前实例self。在结构体和枚举类型中给self赋值会有编译错误,需要在方法前面加上mutating关键字,表明这是变异方法。
调用interestBy1方法计算利息,调用它的实例10_000.00,它的返回值被赋值给interest1常量,这是很常见的调用过程。
调用interestBy2方法计算利息,我们不能使用10_000.00实例调用,而是需要一个Double类型的变量interest2。interestBy2是变异方法,它会直接改变变量interest2的值,因此interest2.interestBy2()语句调用完成后,变量interest2的值就改变了。
调用interestBy3方法计算利息,它是静态方法,调用它需要以“类型名.”的方式即“Double.”的方式调用。
=================================
扩展类型的时候,也可以添加新的构造函数。值类型与引用类型扩展有所区别。值类型包括了除类以外的其他类型,主要是枚举类型和结构体类型。
值类型扩展构造函数
扩展结构体类型中定义构造函数的示例:
[html] view plain copy
print?
struct Rectangle {
var width : Double
var height : Double
init(width : Double, height : Double) {
self.width = width
self.height = height
}
}
extension Rectangle { //定义了Rectangle的扩展类型
init(length : Double) {
self.init(width : length, height : length)
}
}
var rect = Rectangle(width : 320.0, height : 480.0) //调用两个参数的构造函数,这个构造函数是原始类型提供, Rectangle类型已经是扩展类型
print("长方形:\(rect.width) x \(rect.height)")
var square = Rectangle(length: 500.0) //调用一个参数的构造函数,这个构造函数是扩展类型提供的
print("正方形:\(square.width) x \(square.height)")
self.init是调用了原始类型的两个参数的构造函数。
引用类型扩展构造函数
扩展类中定义构造函数的示例:
[html] view plain copy
print?
class Person {
var name : String
var age : Int
func description() -> String {
return "\(name) 年龄是: \(age)"
}
init (name : String, age : Int) {
self.name = name
self.age = age
}
}
extension Person { //定义Person类的扩展类型
convenience init (name : String) { //便利构造函数
self.init(name : name, age : 8)
}
}
let p1 = Person(name : "Mary") //调用两个参数的构造函数,这个构造函数是原始类型提供,这时候的Person类型已经是扩展类型。
print("Person1 : \(p1.description())")
let p2 = Person(name : "Tony", age : 28)// 调用一个参数的构造函数创建Person实例,这个构造函数是扩展类型提供的。
print("Person2 : \(p2.description())")
代码self.init(name :name, age : 8)调用指定构造函数代理部分构造任务。