zoukankan      html  css  js  c++  java
  • 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( 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")
  • 相关阅读:
    当服务器存在多个与公网访问的网卡(对应不同的公网IP地址)时,如何使用指定的网卡进行HTTP请求
    svn 迁移至 git
    在 sql server 中批量删除表
    从高版本的 SQL Server 向低版本的 SQL Server 转移数据
    MYSQL 复制整个数据库
    在 VS Code 中遇到的一些问题
    把TEMPDB放到内存里
    关于在 ASP.NET 的 Global.asax 中 Application_Error 方法内,设置跳转到自定义错误页无效的问题
    重新安装和更新所有的 nuget包
    高版本 MySQL 导出的脚本到低版本 MySQL 中执行时报错
  • 原文地址:https://www.cnblogs.com/huanying2000/p/6406109.html
Copyright © 2011-2022 走看看