iOS --- 扩展和泛型(swift2.3)

来源:互联网 发布:广州电商美工培训 编辑:程序博客网 时间:2024/05/18 04:57

iOS — 扩展和泛型(swift)

下面简单的介绍扩展和泛型的应用

  1. 扩展基础

  2. 嵌套类型

  3. 扩展标准库

  4. 泛型函数

  5. 泛型类型


一:扩展基础

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 中放入新的方法extension Rectangle{//类的扩展中只能扩展方法,计算型属性和convenience的init方法,而类型的存储属性和init方法只能写在类中,这就是扩展,帮助开发者实现多人开发    // 如果是struct,就需要使用mutating关键字    func translate(x x: Double, y: Double){        self.origin.x += x        self.origin.y += y    }}let rect = Rectangle(origin: Point(), size: Size(width: 4, height: 3))rect.translate(x: 10, y: 10)rect// extension 中放入新的属性extension Rectangle{    // extension中只能放入计算型属性    var center: Point{        get{            let centerX = origin.x + size.width/2            let centerY = origin.y + size.height/2            return Point(x: centerX, y: centerY)        }        set(newCenter){            origin.x = newCenter.x - size.width/2            origin.y = newCenter.y - size.height/2        }    }    var area: Double{        return size.width * size.height    }    var perimeter: Double{        return 2*(size.width + size.height)    }    // 可以在extension中根据计算性属性放入新的构造函数    // extension中只能放入convenience的构造函数    convenience init(center: Point, size: Size){        let originX = center.x - size.width/2        let originY = center.y - size.height/2        //self.origin = Point(x: originX, y: originY)        //self.size = size        self.init(origin: Point(x: originX, y: originY), size: size)    }}rect.arearect.perimeterrectlet rect2 = Rectangle(center: Point(), size: Size(width: 6, height: 8))rect2

二:嵌套类型

//nested typeclass UI{    enum Theme{        case DayMode        case NightMode    }    var fontColor: UIColor!    var backgroundColor: UIColor!    var themeMode: Theme = .DayMode{        didSet{            self.changeTheme(self.themeMode)        }    }    init(){        self.themeMode = .DayMode        self.changeTheme(self.themeMode)    }    init(themeMode: Theme){        self.themeMode = themeMode        self.changeTheme(themeMode)    }    func changeTheme( themeMode: Theme ){        switch(themeMode){        case .DayMode:            fontColor = UIColor.blackColor()            backgroundColor = UIColor.whiteColor()        case .NightMode:            fontColor = UIColor.whiteColor()            backgroundColor = UIColor.blackColor()        }    }}let ui = UI()ui.themeModeui.fontColorui.backgroundColorui.themeMode = .NightModeui.themeModeui.fontColorui.backgroundColor// 以前就见过Nest Type这个就是一个嵌套的枚举类型,Index就是定义在string类里面的类型// String.Indexlet str = "Hello World"let index = str.startIndex.advancedBy(5)str.substringToIndex(index)//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 中放入 Nested Type, Methods 和 subscriptextension Rectangle{    // extension 中放入 Nested Type    enum Vertex: Int{        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 )        case .LeftBottom:            return Point(x: origin.x, y: origin.y + size.height )        }    }    // extension 中放入 subscript    subscript(index: Int) -> Point{        //assert的功能在于:如果index参数不满足条件,那么就会打印出Index in Rectange Out of Range.        assert( index >= 0 && index < 4 , "Index in Rectange Out of Range.")        return pointAtVertex(Vertex(rawValue: index)!)    }}let rect = Rectangle(origin: Point(), size: Size(width: 4, height: 3))rect.pointAtVertex(.RightBottom)rect[0]rect[1]rect[2]rect[3]

三:扩展标准库

extension Int{    var square: Int{//扩充标准库的计算属性        return self*self    }    var cube: Int{        return self*self*self    }    //扩充方法    func inRange(closedLeft left: Int, openedRight: Int) -> Bool{        return self >= left && self < openedRight    }    //这里的参数的类型是个函数    func repetitions(task: () -> Void ){        for _ in 0..<self{            task()        }    }    func stride(to end: Int, by stride: Int, task: (Int) -> Void ){        for i in self.stride(to: end, by: stride){            task(i)        }    }}let num = 8num.squarelet str = "Hello, Swift"let index = 21index.inRange(closedLeft: 0, openedRight: str.characters.count)10.repetitions{    print("Hello, Swift")}for i in 2.stride(to: 10, by: 2){    print(i)}for i in 2.stride(through: 10, by: 2){    print(i)}2.stride(to: 10, by: 2){ num in    print(num*num)}// Int还有很多可以做enxtension的地方// 如 12345[2]// 如 toBinary, toHex// 如 isPrime// extension在App开发中被经常使用// 如 String, UIColor等基础类的使用// 在App开发中, 一个界面可能需要处理多个事件: 表格显示, 用户输入, 导航, 动画, 数据存储...// 此时可以使用extension分隔开

四:泛型函数

func swapTwoInt(inout a: Int , inout _ b: Int){//这里的inout关键字表面:参数的传递是按照引用传递的    (a,b) = (b,a)}var a: Int = 0var b: Int = 6swapTwoInt(&a, &b)abfunc swapTwoDouble(inout a: Double , inout _ b: Double){    (a,b) = (b,a)}// 使用generic// generic function(泛型函数):前面两个函数的意思其实是一样的,就是交换两个参数的值,只是类型不一样,这样做产生了冗余的代码,下面这个swapTwoThings函数为我们引出了泛型的概念,<T>:表示这个函数的参数的类型是T,那么无论我们传入的是int类型的参数还是string类型,只要定义了这个泛型函数的逻辑,传入参数的任意类型都能使用这个逻辑,扩展了函数的通用性func swapTwoThings<T>(inout a: T , inout _ b: T){    (a,b) = (b,a)}var hello = "Hello"var bye = "Bye"swapTwoThings(&hello, &bye)hellobyeswapTwoThings(&a, &b)abswap(&a, &b)

五:泛型类型

// generic typelet arr = Array<Int>()let dict = Dictionary<String,Int>()let set  = Set<Float>()//注意:一个空数组的声明有两种写法,利用inference可以知道aaa和b的数据类型是个数组let aaa = [Int]()let b = Array<Int>()struct Stack<T>{//<T>表示stack里面的数据类型是任意的    var items = [T]()//在这里声明一个T类型的数组//    //当然声明一个空数组也可以这样写://    var items1:Array<T> = [T]()//    //    //或者这么写//    var items2:Array<T> = Array<T>()    func isEmpty() -> Bool{//返回值为bool类型的函数,用来判断数组是否为空        return items.count == 0    }    mutating func push(item: T){//由于stack是一个结构体,这个push函数改变了结构体中的数据,那么应该使用mutating关键字        items.append(item)    }    mutating func pop() -> T?{        guard !self.isEmpty() else{            return nil        }        return items.removeLast()    }}extension Stack{    func top() -> T?{        return items.last    }    func count() -> Int{        return items.count    }}var s = Stack<Int>()s.push(1)s.push(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")pair.apair.b
0 0
原创粉丝点击