[Swift]扩展
来源:互联网 发布:类似弹个车的软件 编辑:程序博客网 时间:2024/06/09 23:05
1. Swift扩展的概念以及重要性:
1) 扩展的概念:是指向一个已有的类、结构体、枚举添加新的功能(属性、方法、下标等),但不需要修改这些类型的源代码甚至不需要拥有这些类型的源代码;
2) 和继承的区别:首先扩展可以运用到不止类(还包括结构体和下标,甚至是Int、Double等基本类型,实际上这些基本类型也是用结构体来实现的);
其次,虽然可以通过继承在新的子类中添加更多的功能,但是继承机制比较复杂而有时作者会限制类的继承(比如使用final声明等),但是扩展不受这些约束(比如一个类被声明为final的,虽然其不可被继承,但是仍然可以对其进行扩展):
final class A { }extension A { // OK! 虽然不能继承但是仍能扩展 func f() { println("haha") }}这里提一下扩展的语法:
extension 类名 { 扩展的内容...}3) 扩展的作用:
i) 特别是在没有权限获取源代码的情况下也可以扩展类型,提高了逆向建模的能力;
ii) 可以说扩展是一种轻量级的继承;
iii) 在任何时候都要优先考虑使用扩展(一般Java程序员都会保守地选择继承),这是从简的编程原则,只有当扩展无法满足需求的时候再考略使用继承;
iv) 扩展在Swift中地位非常重要,很多Swift API以及一些Swift的基本类型都是通过扩展实现的,比如String的很多方法就是通过扩展实现的;
4) 可以对基本类型进行扩展,比如Int、String、Double、Character等,因为这些基本类型底层都是用结构体包装的!
5) Swift允许扩展的内容:
i) 对于值类型(结构体和枚举)可以扩展静态存储属性,但是对于类类型则不能扩展静态存储属性;
ii) 对于任何类型都不能扩展实例存储属性;
iii) 可以扩展计算属性(实例、静态都行);
iv) 可以扩展方法(实例、静态都行);
v) 可以扩展构造器;
vi) 可以扩展下标;
vii) 可以扩展嵌套类;
viii) 可以扩展使其适配一个或多个协议;
6) 扩展的最大亮点:在定义扩展后全局有效,即那些在扩展前定义的对象也可以使用扩展出的新功能;
2. 扩展静态存储属性:
1) 只对于值类型成立;
2) 举例:
extension Int { static var sta_var = 90 // OK! Int是值类型的结构体}class A { }//extension A {// static var test = 11 // Bad! 不能扩展类类型的静态存储属性//}struct B { }extension B { static var test = 11 // OK! 结构体类型可以}enum C { }extension C { static var test = 22 // OK! 枚举类型也是值类型,同样也可以扩展静态存储属性}3) 但是对于任何类型都不能扩展实例存储属性!
3. 扩展计算属性:!注意值类型和枚举类型之间的区别
extension Int { var errMessage: String { // 扩展实例的只读计算属性 switch self { case -7: return "没有数据" case -6: return "日期格式有误" case -5: return "内容格式有误" case -4: return "ID为空" case -3: return "数据访问失败" case -2: return "空间不足" case -1: return "用户不存在" default: return "" } }}println((-3).errMessage) // 数据访问失败,注意使用括号否则编译解析会有问题struct A { }extension A { static var x = 10 // 扩展静态存储属性 var y: Int { // 扩展实例可读可写计算属性对静态存储属性进行维护 get { return A.x } set { A.x = newValue } }}println(A.x) // 10var a = A()println(a.y) // 10a.y = 30println(A.x) // 30extension Double { // 模拟单位表示法 var km: Double { return self * 1_000.0 } var m: Double { return self } var cm: Double { return self / 100.0 } var mm: Double { return self / 1_000.0 }}var some_km = 5.0.kmvar some_m = 3.9.mvar some_cm = 90.3.cmvar some_mm = 33.23.mmprintln(some_km) // 5000.0println(some_m) // 3.9println(some_cm) // 0.903println(some_mm) // 0.03323class B { }extension B { class var test: Int { // 扩展静态计算属性 return 23 }}
4. 扩展构造器:
对于结构体可以扩展普通构造器和代理构造器,但是对于类只能扩展便利构造器但不能扩展指定构造器!
struct A { var a = 15 var b = 20 init(a: Int, b: Int) { self.a = a self.b = b }}extension A { // 对于结构体既可以扩展普通构造器也可以扩展代理构造器 init(a: Int) { self.a = a } init() { self.init(a: 23, b: 88) }}extension A { // 可以连续扩展任意多次 init(s: String) { self.init() }}class B { var a: Int var b: Int init(a: Int, b: Int) { self.a = a self.b = b }}extension B { // 对于类只能扩展便利构造器不能扩展指定构造器,否则会报错! // !由于类只能扩展便利构造器而不能扩展指定构造器,因此就不能用super调用父类构造器了! convenience init() { self.init(a: 10, b: 20) }}
5. 扩展方法:
按照之前讲过的定义方法的规则可以随意扩展:
extension Double { static let rate = 3.773 // 结构体可以扩展静态存储结构 func getTotal() -> Double { // 扩展实例方法 return Double.rate * self } static func computeTotal(amount: Double) -> Double { // 扩展静态方法 return rate * amount } mutating func doubleIt() { // 要改变结构体本身的内容需要变异! self = self * 2 }}class A { // 注意!类只支持静态计算属性不支持静态存储属性 var value: Double = 234.32}// 相应的类类型的版本extension A { class var rate: Double { return 3.231 } func getTotal() -> Double { return value * A.rate } class func computeTotal(amount: Double) -> Double { return rate * amount } func doubleIt() { value = value * 2 }}一个扩展方法的非常有趣的例子:为Int扩展一个方法,使用Int的数值n重复n次动作,这个动作作为闭包作为参数传入扩展的方法
extension Int { func rep(task: () -> ()) { for _ in 0..<self { task() } }}3.rep { println("haha") }
就跟普通定义下标一样,这里介绍两个扩展String和Int下标的有趣的例子:
扩展String下标,用来模仿C语言字符数组随机访问的功能
extension String { subscript(index: Int) -> String { // 返回的字符用String包装 if index < 0 || index + 1 > countElements(self) { return "" } var i = 0 for char in self { // 从字符串中取出的元素是Character类型的 if i == index { return String(char) // 需要包装成String类型 } i++ } return "" }}println("abc"[2]) // c扩展Int下标,获得从低到高的第n位数字,第0位是最低位:
extension Int { subscript(index: Int) -> Int { var base = 1 for _ in 0..<index { base *= 10 } return (self / base) % 10 }}println(23423[2]) // 4
6. 扩展嵌套类型:
就和定义普通的嵌套类型一样,这里介绍一下在Character中扩展一个枚举类型,用于对字符的类型进行分类(元音、辅音等):
extension Character { enum Kind: String { case Vowel = "Vowel" case Consonant = "Consonant" case Other = "Other" } var kind: Kind { switch String(self).lowercaseString { case "a", "e", "i", "o", "u": return .Vowel case "b", "c", "d", "f", "g": return .Consonant default: return .Other } }}println(Character("I").kind.rawValue) // Vowel
7. 扩展适配协议:
可以扩展一个类型使其匹配一个或多个协议,这里只介绍其语法:
extension Type: Protocol1, Protocol2... { ...}
- [Swift]扩展
- Swift-扩展
- Swift 扩展
- Swift-扩展
- swift 扩展
- Swift 扩展
- swift 协议和扩展
- Swift-协议和扩展
- Swift 扩展(十七)
- Swift扩展(Extension)
- Swift扩展(Extensions)
- 20.Swift-扩展
- Swift教程之扩展
- swift strinng的扩展
- Swift(二十、扩展)
- Swift String 扩展
- UIColor扩展—Swift
- Swift学习之扩展
- code signing is required for product type 'Application' in SDK 'iOS 8.1'
- C#在方法或属性中使用sealed时的操作与原理
- hdu 5128 The E-pang Palace(计算几何:暴力枚举)
- 伪静态
- 蓝桥杯 - 核桃的数量
- [Swift]扩展
- 数据结构之线索二叉树
- Binary Tree Level Order Traversal II
- 十一月总结
- LA 6540 Fibonacci Tree
- maven报错非法字符:\65279 错误
- 【转】sublime中BracketHighlighter插件高亮设置方法
- 【工程数学】若干种计算圆周率的算法
- 【构造】 FZU 2140 Forever 0.5