Swift编程中的泛型解析
泛型代码可以让你写出根据自我需求定义、适用于任何类型的,灵活且可重用的函数和类型。它可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码的意图。 复制代码 代码如下: func swapTwoInts(inout a: Int,inout b: Int) let temporaryA = a a = b b = temporaryA } 这个函数使用写入读出(in-out)参数来交换a和b的值,请参考写入读出参数。 swapTwoInts函数可以交换b的原始值到a,也可以交换a的原始值到b,你可以调用这个函数交换两个Int变量值: 复制代码 代码如下: var someInt = 3 var anotherInt = 107 swapTwoInts(&someInt,&anotherInt) println("someInt is now (someInt),and anotherInt is now (anotherInt)") // 输出 "someInt is now 107,and anotherInt is now 3" swapTwoInts函数是非常有用的,但是它只能交换Int值,如果你想要交换两个String或者Double,就不得不写更多的函数,如 swapTwoStrings和swapTwoDoublesfunctions,如同如下所示: func swapTwoStrings(inout a: String,inout b: String) { let temporaryA = a a = b b = temporaryA } func swapTwoDoubles(inout a: Double,inout b: Double) { let temporaryA = a a = b b = temporaryA } 你可能注意到 swapTwoInts、 swapTwoStrings和swapTwoDoubles函数功能都是相同的,唯一不同之处就在于传入的变量类型不同,分别是Int、String和Double。 但实际应用中通常需要一个用处更强大并且尽可能的考虑到更多的灵活性单个函数,可以用来交换两个任何类型值,很幸运的是,泛型代码帮你解决了这种问题。(一个这种泛型函数后面已经定义好了。) 注意: 在所有三个函数中,a和b的类型是一样的。如果a和b不是相同的类型,那它们俩就不能互换值。Swift 是类型安全的语言,所以它不允许一个String类型的变量和一个Double类型的变量互相交换值。如果一定要做,Swift 将报编译错误。 泛型函数:类型参数 复制代码 代码如下: func exchange<T>(inout a: T,inout b: T) { let temp = a a = b b = temp } var numb1 = 100 println("Before Swapping Int values are: (numb1) and (numb2)") var str1 = "Generics" println("Before Swapping String values are: (str1) and (str2)") 当我们使用 playground 运行上面的程序,得到以下结果 Before Swapping Int values are: 100 and 200 After Swapping Int values are: 200 and 100 Before Swapping String values are: Generics and Functions After Swapping String values are: Functions and Generics 函数 exchange()用于交换其在上述方案中描述和<T>被用作类型参数值。这是第一次,函数 exchange()被调用返回Int值,第二次调用函数 exchange()将返回String值。多参数类型可包括用逗号分隔在尖括号内。 类型参数被命名为用户定义来了解拥有类型参数的目的。 Swift 提供<T>作为泛型类型参数的名字。 但是型像数组和字典参数也可以命名为键,值,以确定它们输入属于“字典”。 泛型类型 复制代码 代码如下: struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push("Generics") tos.push("Type Parameters") tos.push("Naming Type Parameters")
当我们使用 playground 运行上面的程序,得到以下结果 [Swift] [Swift,Generics] [Swift,Generics,Type Parameters] [Swift,Type Parameters,Naming Type Parameters] 扩展泛型类型 复制代码 代码如下: struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { var tos = TOS<String>() tos.push("Generics") tos.push("Type Parameters") tos.push("Naming Type Parameters") extension TOS { if let first = tos.first { 当我们使用 playground 运行上面的程序,得到以下结果 [Swift] [Swift,Naming Type Parameters] 在堆栈顶部的项目命名类型参数。 类型约束 复制代码 代码如下: func exchange<T>(inout a: T,&numb2) println("After Swapping Int values are: (numb1) and (numb2)") println("Before Swapping String values are: (str1) and (str2)") 当我们使用 playground 运行上面的程序,得到以下结果 Before Swapping Int values are: 100 and 200 After Swapping Int values are: 200 and 100 Before Swapping String values are: Generics and Functions After Swapping String values are: Functions and Generics 关联类型 复制代码 代码如下: protocol Container { typealias ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } } struct TOS<T>: Container { // conformance to the Container protocol subscript(i: Int) -> T { var tos = TOS<String>() tos.push("Generics") tos.push("Type Parameters") tos.push("Naming Type Parameters") 当我们使用 playground 运行上面的程序,得到以下结果 [Swift] [Swift,Naming Type Parameters] Where 子句 复制代码 代码如下: protocol Container { typealias ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } } struct Stack<T>: Container { mutating func pop() -> T { // conformance to the Container protocol subscript(i: Int) -> T { func allItemsMatch< // check each pair of items to see if they are equivalent var tos = Stack<String>() tos.push("Generics") tos.push("Where Clause") var eos = ["Swift","Generics","Where Clause"] 当我们使用 playground 运行上面的程序,得到以下结果 [Swift] [Swift,Where Clause] [Swift,Where Clause] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |