Generics

/* 范型 Generics C++中的模版函数,模板类

1.范型函数

2.Generic Type

3.范型类型的扩展

4.范型类型约束(给T加一个约束,不是所有类型都可以用)

5.typealias定义范型

6.可以用where语句来对类型参数列表进行限制

*/


//1.范型函数

func testGenerics<MyType1, MyType2>(para1: MyType1, para2: MyType2)

{

    //由于println本身是范型的,这里为了简单说明直接这样测试

    println(para1)

    println(para2)

}


testGenerics("hello", 3)

testGenerics("hello", "Hello2")


//2.范型类型 可以是类,结构体,枚举等

// 堆栈的例子,这里为了将重点放在范型类型上,没有容错

struct Stack<T>

{

    var items = [T]()

    

    mutating func push(newitem: T)

    {

        println("Push a newitem \(newitem)")

        self.items.append(newitem)

    }

    

    mutating func pop() -> T

    {

        println("pop a item")

        return self.items.removeLast()

    }

}


//类型的创建实例,可以看到之前数组Array<Int>(),Dictionary<keyType,valueType>()都是范型

var s = Stack<Int>() //函数范型在调用的时候不需要带类型,但是类型需要带

s.push(3)

s.pop()


//3.范型类型的扩展,不需要向定义一样需要提供类型T(类型参数列表),直接用就可以。

extension Stack

{

    var topItem: T?{

    return items.isEmpty ? nil : items[items.count - 1]

    }

}


//4.范型类型约束

//下面这个函数定义了类型参数列表的约束,T必须是SomeCLass的子类,U必须是某协议的遵循者

//Generic Type的定义方法和这个类似

//func someFunction<T: SomeClass, U: SomeProtocol>(para1: T, para2: U){ }

func findIndex<T>(array:[T], value:T, isEqual:(T, T)->Bool)->Int? {

    for (index, item) in enumerate(array) {

        if isEqual(item, value) {

            return index

        }

    }

    return nil

}

//上面的函数如果要求类型T必须遵循系统库协议Equatable,即可以用==进行比较的协议,就会简单一些

func findIndex2<T: Equatable>(array: [T], value:T) -> Int? {

    for (index, item) in enumerate(array) {

        if item == value {

            return index

        }

    }

    return nil

}


//5.typealias创建范型协议

protocol Container {

    typealias ItemType

    mutating func append(item: ItemType)

    var count: Int { get }

    subscript(i: Int)->ItemType { get }

}


class IntStack: Container {

    var items = [Int]()

    func push(item: Int) {

        items.append(item)

    }

    func pop() -> Int {

        return items.removeLast()

    }

    

    // typealias ItemType = Int在实现的时候可以不定义,swift可以自行推导出。

    typealias ItemType = Int

    

    func append(item: ItemType) {

        self.push(item)

    }

    var count: Int {

        return items.count

    }

    subscript(i: Int) -> Int {

        return items[i]

    }

}


// where语句对类型参数列表进行限制

//Array已经有Container的方法,但是并不是Container的遵循者,加上用于下面的测试

extension Array: Container{}


func allItemsMatch<C1:Container, C2:Container where C1.ItemType == C2.ItemType,

    C1.ItemType:Equatable> (container1: C1, container2: C2)->Bool {

        if container1.count != container2.count

        {

            return false

        }

        for i in 0..<container1.count {

            if container1[i] != container2[i] {

                return false

            }

        }

        return true

}


var a1 = [1,2,3]

var a2 = ["ok", "hi", "test"]

allItemsMatch(a1, a2) //ERROR 在函数定义时,要求两个类型需要一致,这里不同会报错。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值