本文首发地址
请在阅读本文章时,顺手将文中的示例代码在playground中敲一遍,这样能加深理解!!!
阅读该文章大约须要:15分钟
读完以后你能得到:
一、Extension是什么
二、它能作什么javascript
extension SomeType {
// new functionality to add to SomeType goes here
}复制代码
Tip:扩展能够为一个类型添加新的功能,可是不能重写已有的功能。
html
struct Student {
var name = ""
var age = 1
func print() {
}
}
extension Student {
//改行会报错`invalid redeclaration print()`重复声明print(),重写变量也是不行的。
func print() {
}
}复制代码
咱们想知道Extension在Swift中能作些什么,最直接的方法就是查看Swift的官方文档了。下面是文档中指出Extension能作的六个方面。java
看完上面Extension能作的六个方面,咱们来逐条解释说明一下:git
首先咱们要了解什么是计算型属性,计算型属性(computed property)不直接存储值,而是提供一个getter
和一个可选的setter
,来间接获取和设置其余属性或变量的值。关于更多的计算型属性的内容请自行查看官方文档,在此再也不赘述。那么咱们什么场景能够用到这个功能呢?举一个最多见的例子,当你想访问某个view的width的时候,一般状况下你会这么写:程序员
view.frame.size.width复制代码
可是这样写很长很不方便,做为一个懒惰的程序员,这时候你就要想我能不能缩短访问该属性的代码。不要犹豫了骚年,这时候你只须要写一个UIView的Extension就能够达到你的目的。github
extension UIView {
var x: CGFloat {
set {
self.frame.origin.x = newValue
}
get {
return self.frame.origin.x
}
}
var y: CGFloat {
set {
self.frame.origin.y = newValue
}
get {
return self.frame.origin.y
}
}
var width: CGFloat {
set {
self.frame.size.width = newValue
}
get {
return self.frame.size.width
}
}
var height: CGFloat {
set {
self.frame.size.height = newValue
}
get {
return self.frame.size.height
}
}
}复制代码
这样你就能够经过来访问该属性。怎么样,有没有感觉到Extension的便利之处。swift
view.width复制代码
在你辛辛苦苦写完一个Student类后,万恶的产品过来告诉你需求改了,这时虽然你心中有一万只草泥马在奔腾,可是为了心中那份神圣的程序员的责任感(固然还有糊口的工资),你仍是要修改代码。若是你想在不改变原始类的基础上添加功能,那你能够给Student类添加Extension来解决问题。app
Tip:这里值得注意的一点是在Swift中,Extension能够给类和类型添加,好比你也能够给一个struct添加Extension,而在Objective-C中,你只能给类添加Extension。
ui
class Student {
var name = ""
var age = 1
}
extension Student {
func printCurrentStudentName() {
print(self.name)
}
}
var jack = Student()
jack.name = "jack"
jack.printCurrentStudentName()复制代码
最多见的Rect一般由origin
和size
来构造初始化,可是若是在你写完Rect的定义后,你恰恰想要经过center和size来肯定Rect(做为一个程序员就要有一种做死的精神),那你就要用Extension来给Rect提供一个新的构造器。关于更多关于构造器的信息,请参考官方文档spa
本例子来源官方文档
struct Size {
var width = 0.0, height = 0.0
}
struct Point {
var x = 0.0, y = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
}
let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
size: Size(width: 5.0, height: 5.0))复制代码
经过Extension来给Rect添加一个新的构造器。
extension Rect {
init(center: Point, size: Size) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init(origin: Point(x: originX, y: originY), size: size)
}
}复制代码
这样你就能够经过新的构造器来初始化Rect。
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
size: Size(width: 3.0, height: 3.0))
// centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)复制代码
经过Swift中的Extension,你能够给已知类型添加下标。例以下面的例子就是给Int
类型添加一个下标,该下标表示十进制数从右向左的第n个数字。
本例子来源官方文档
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
746381295[0]
// 5
746381295[1]
// 9复制代码
Extensions能够给已知的类、结构体、枚举添加嵌套类型。下面的例子是给Int类型添加一个判断正负数的Extension,该Extension嵌套一个枚举。
本例子来源官方文档
extension Int {
enum Kind {
case negative, zero, positive
}
var kind: Kind {
switch self {
case 0:
return .zero
case let x where x > 0:
return .positive
default:
return .negative
}
}
}
func printIntegerKinds(_ numbers: [Int]) {
for number in numbers {
switch number.kind {
case .negative:
print("- ", terminator: "")
case .zero:
print("0 ", terminator: "")
case .positive:
print("+ ", terminator: "")
}
}
print("")
}
printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
// Prints "+ + - 0 - 0 + "复制代码
编写使该类型遵照某个协议的Extension的语法以下:
extension SomeType: SomeProtocol, AnotherProtocol {
// implementation of protocol requirements goes here
}复制代码
示例代码:
protocol StudentProtocol {
var address: String { get }
}
struct Student {
var name = ""
var age = 1
}
extension Student: StudentProtocol {
var address: String {
return "address"
}
}
var jack = Student()
jack.address
//输出 address复制代码
若添加Extension的类型已经实现协议中的内容,你能够写一个空的Extension来遵照协议:
protocol StudentProtocol {
var address: String { get }
}
struct Student {
var address: String {
return "address"
}
var name = ""
var age = 1
}
extension Student: StudentProtocol {}
var jack = Student()
jack.address
//输出 address复制代码
下篇预告:Swift-Protocol
若本文有何错误或者不当之处,还望不吝赐教。谢谢!