Swift 学习笔记,扩展和泛型

在开始介绍Swift中的扩展之前,我们先来回忆一下OC中的扩展。

在OC中如果我们想对一个类进行功能的扩充,我们会怎么做呢。

对于面向对象编程的话,首先会想到继承,但是继承有两个问题。

第一个问题:继承的前提是这个类可以被继承,在Swift中又不可以被继承的类 final,OC中也有不可以被继承的类

第二个问题:继承是侵入性的,就是我们可能只是想实现一个功能,但是继承之后,子类就会把父类的所有功能(属性和方法)都继承了,这个代价太大。

所以OC给我们提供了一种很强大的解决方式,使用类别扩展。

NSString+Extension.h

#import <Foundation/Foundation.h>

@interface NSString (Extension)

- (BOOL)validateEmial;

- (NSInteger)intValue;

@end

NSString+Extension.m

#import "NSString+Extension.h"

@implementation NSString (Extension)

- (BOOL)validateEmial {
    NSRange range = [self rangeOfString:@"@"];
    if (range.location == NSNotFound) {
        return NO;
    }else {
        return YES;
    }
}
//当类别中出现了已有的方法,会覆盖原有的实现方法。
- (NSInteger)intValue {
    NSLog(@"intValue");
    return 0;
}

@end

这里我们就定义了一个类目,下面来解释一下:

类别文件的定义格式:"需要添加类别的类名+类别的名称"

上面是OC中为一些类添加新的功能。那么在Swift中我们应该怎么做呢。其实Swift为我们提供了一个关键字 extension 来表明为一个类进行扩展。

代码示例:

//为String扩展功能
extension String {
    func validateEmial() -> Bool {
        let rang = self.range(of: "@")
        if (rang != nil) {
            return false
        }else {
            return true
        }
    }
}
//使用
let str1 = "@123"
if str1.validateEmial() {
    print("为真")
}else {
    print("为假")
}

扩展计算型的属性(扩展属性是有局限性的 只能扩展计算型属性)

虽然不能扩展存储型属性 但是我们可以在自己扩展的计算型属性中改变存储型属性

extension Double {
    var KM:Double{
        return self * 1000.0
    }
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
}
let oneInch = 24.5.KM//24500

也可以在扩展中扩展新的构造函数,但是这个构造函数必须是便利构造函数。

struct Point {
    var x = 0.0
    var y = 0.0
}

struct Size {
    var width = 0.0
    var height = 0.0
}

class Rectangle {
    var origin = Point()
    var size = Size()
    init(origin:Point,size:Size) {
        self.origin = origin
        self.size = size
    }
}

//扩展
extension Rectangle {
    func translate(x:Double,y:Double) {
        self.origin.x += x
        self.origin.y += y
    }
}
let rect = Rectangle(origin: Point(), size: Size(width: 10, height: 10))
//调用扩展方法
rect.translate(x: 10, y: 10)

extension Rectangle {
    var center:Point {
        get {
            return Point(x: origin.x + size.width / 2, y: origin.y + size.height / 2)
        }
        set(newCenter) {
            //存储型属性可以在扩展的计算型属性中被修改
            origin.x = newCenter.x - size.width/2
            origin.y = newCenter.y - size.height/2
        }
    }
    //扩展构造器
    convenience 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)
    }
}

内嵌类型

class UI {
    //UI类型的内嵌类型
    enum Theme {
        case DayModel
        case NightModel
    }
    
    var fontColor: UIColor!
    var backgroundColor: UIColor!
    var themeModel:Theme = .DayModel {
        didSet {
            self.changeModel(themeModel: themeModel)
        }
    }
    
    init() {
        self.themeModel = .DayModel
        self.changeModel(themeModel: self.themeModel)
    }
    func changeModel(themeModel:Theme){
        switch themeModel {
        case .DayModel:
            self.fontColor = UIColor.white
            self.backgroundColor = UIColor.black
        default:
            self.fontColor = UIColor.black
            self.backgroundColor = UIColor.white
        }
    }
}
let ui = UI()
ui.themeModel//类型UI.Theme

扩展内嵌类型

extension Rectangle {
    enum Vertex {
        case LeftTop
        case RightTop
        case RightBottom
        case LeftBottom
    }
    func pointAtVertex(v:Vertex) -> Point {
        switch v {
        case .LeftTop:
            return origin
        case .RightTop:
            return Point(x: origin.x + size.width, y: origin.y)
        case .RightBottom:
            return Point(x: origin.x + size.width, y: origin.y + size.height)
        default:
            return Point(x: origin.x, y: origin.y + size.height)
        }
    }
}

扩展标准库

extension Int {
    var square:Int {
        
        return self * self
    }
    var cube:Int {
        return self * self * self
    }
    func inRange(closeLeft:Int,openEndRight:Int)->Bool {
        return self >= closeLeft && self < openEndRight
    }
    //封装一个重复若干次的动作
    func repetitions(task:()->()) {
        for _ in 0..<self {
            task()
        }
    }
    
}
let index = 12
index.inRange(closeLeft: 11, openEndRight: 17)

index.repetitions {
    print("重复的逻辑")
}

泛型

//<T>定义的一个泛型 可以是任何类型
func swapTwoThings<T>( a:inout T,b:inout T) {
    (a,b) = (b,a)
}

var tian = "hahahaha"
var lian = "heiheihei"
swapTwoThings(a: &tian, b: &lian)

var a = 0
var b = 6
swapTwoThings(a: &a, b: &b)

泛型类型

把泛型应用到某种类型中就是泛型类型例如:arr:Array<Int> = Array<Int>()就是一个泛型类型。

//栈 可以存储任何类型的数据 所以我们可以使用泛型 本质为数组
struct Stack<T> {
    var items = [T]()
    func isEmpty() ->Bool {
        return items.count == 0
    }
    mutating func push(item:T) {
        items.append(item)
    }
    mutating func pop() ->T? {
        guard !self.isEmpty() else {
            return nil
        }
        return items.removeLast()
    }
}
//查看栈顶元素
extension Stack {
    func top() -> T? {
        return items.last
    }
}


var s = Stack<Int>()
s.push(item: 1)
s.push(item: 2)
s.pop()
var ss = Stack<String>()

struct Pair <T1,T2> {
    var a:T1
    var b:T2
}

var pair = Pair<Int,String>(a:0,b:"hello")