《swift2.0 官方教程中文版》 第2章-23泛型

前端之家收集整理的这篇文章主要介绍了《swift2.0 官方教程中文版》 第2章-23泛型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。


import Foundation


/*泛型所解决的问题*****************************************************/

//这里是一个标准的,非泛型函数 swapTwoInts,用来交换两个Int:

func swapTwoInts(inout a: Int,inout _ b: Int) {

let temporaryA = a

a = b

b = temporaryA

}


var someInt = 3

var anotherInt = 107

swapTwoInts(&someInt,&anotherInt)

print("someInt is now \(someInt),and anotherInt is now \(anotherInt)")

// 输出 "someInt is now 107,and anotherInt is now 3"


//swapTwoInts(_:_:) 函数是非常有用的,但是它只能交换 Int ,如果你想要交换两个 String 或者 Doubl e,就不得不写更多的函数, swapTwoStrings swapTwoDoubles(_:_:),如同如下所示:

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 swapTwoValues<T>(inout a:T,inout _ b:T) {

let temporaryA = a

a = b

b = temporaryA

}

var someInt1 = 3

var anotherInt1 = 107

swapTwoValues(&someInt1,&anotherInt1)

print("someInt1 is now \(someInt1),and anotherInt1 is now \(anotherInt1)")

// someInt 现在等于 107,anotherInt 现在等于 3


var someString = "hello"

var anotherString = "world"

swapTwoValues(&someString,&anotherString)

print("someInt is now \(someString),and anotherInt is now \(anotherString)")

// someString 现在等于 "world",anotherString 现在等于 "hello"




/*类型参数*****************************************************/




/*命名类型参数*****************************************************/

//如果你使用多个参数定义更复杂的泛型函数或泛型类型,那么使用更多的描述类型参数是非常有用的。例如,Swi ft 字典(Dictionary)类型有两个类型参数,一个是键,另外一个是值。如果你自己写字典,你或许会定义这两 个类型参数为 Key Value,用来记住它们在你的泛型代码中的作用。

//注意 请始终使用大写字母开头的驼峰式命名法(例如 T Key )来给类型参数命名,以表明它们是类型的占 位符,而非类型值。




/*泛型类型*****************************************************/

struct IntStack {

var items = [Int]()

mutating func push(item:Int){

items.append(item)

}

mutating func pop() -> Int {

return items.removeLast()

}

}


struct Stack<T> {

var items = [T]()

mutating func push(item: T) {

items.append(item)

}

mutating func pop() -> T {

return items.removeLast()

}

}

//T 定义了一个名为某种类型T”的节点提供给后来用。这种将来类型可以在结构体的定义里任何地方表示 “T”。在这种情况下,T 在如下三个地方被用作节点:

//? 创建一个名为 items 属性,使用空的T类型值数组对其进行初始化;

//? 指定一个包含一个参数名为 item push(_:) 方法,该参数必须是T类型;

//? 指定一个 pop 方法的返回值,该返回值将是一个T类型值。


var stackOfStrings = Stack<String>()

stackOfStrings.push("uno")

stackOfStrings.push("dos")

stackOfStrings.push("tres")

stackOfStrings.push("cuatro")

// 现在栈已经有4string

let fromTheTop = stackOfStrings.pop()

print("\(stackOfStrings)")

// fromTheTop 等于 "cuatro",现在栈中还有3string




/*扩展一个泛型类型*****************************************************/

extension Stack {

var topItem: T? {

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

}

}

//topItem 属性会返回一个 T 类型的可选值。当栈为空的时候,topItem 将会返回 nil ;当栈不为空的时候,Item 会返回 items 数组中的最后一个元素。

if let topItem = stackOfStrings.topItem {

print("The top item on the stack is \(topItem).")

}

// 输出 "The top item on the stack is tres."




/*类型约束*****************************************************/

//func someFunction<T: SomeClass,U: SomeProtocol>(someT: T,someU: U) {

// // 这里是函数主体

//}


//这里有个名为 findStringIndex 的非泛型函数,函数功能是去查找包含一给定 String 值的数组。若查找到匹配 的字符串,findStringIndex(_:_:) 函数返回该字符串在数组中的索引值( Int ),反之则返回 nil :

func findStringIndex(array: [String],_ valueToFind: String) -> Int? {

for(index,value) in array.enumerate() {

if value == valueToFind {

return index

}

}

return nil

}

let strings = ["cat","dog","llama","parakeet","terrapin"]

if let foundIndex = findStringIndex(strings,"llama") {

print("The index of llama is \(foundIndex)")

}

// 输出 "The index of llama is 2"


func findIndex<T:Equatable>(array:[T],_ valueToFind:T) -> Int? {

for(index,value) in array.enumerate() {

if value == valueToFind {

return index

}

}

return nil

}

let doubleIndex = findIndex([3.14159,0.1,0.25],9.3)

print("索引号是\(doubleIndex)")

// doubleIndex is an optional Int with no value,because 9.3 is not in the array

let stringIndex = findIndex(["Mike","Malcolm","Andrea"],"Andrea")

print("索引号是\(stringIndex)")

// stringIndex is an optional Int containing a value of 2




/*关联类型*****************************************************/

protocol Container {

typealias ItemType

mutating func append(item: ItemType)

var count: Int{ get }

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

}


struct IntStack2: Container {

// IntStack的原始实现

var items = [Int]()

mutating func push(item: Int) {

items.append(item)

}

mutating func pop() -> Int {

return items.removeLast()

}

// 遵循Container协议的实现

typealias ItemType = Int

mutating func append(item: Int) {

self.push(item)

}

var count: Int {

return items.count

}

subscript(i: Int) -> Int {

return items[i]

}

}


struct Stack2<T>: Container {

// original Stack<T> implementation

var items = [T]()

mutating func push(item: T) {

items.append(item)

}

mutating func pop() -> T {

return items.removeLast()

}

// conformance to the Container protocol

mutating func append(item: T) {

self.push(item)

}

var count: Int {

return items.count

}

subscript(i: Int) -> T {

return items[i]

}

}




/*Where 语句*****************************************************/

//下面的例子定义了一个名为 allItemsMatch 的泛型函数,用来检查两个Container实例是否包含相同顺序的相同 元素。如果所有的元素能够匹配,那么返回一个为 true Boolean ,反之则为 false

func allItemsMatch<C1:Container,C2:Container

where C1.ItemType == C2.ItemType,C1.ItemType: Equatable>

(someContainer: C1,anotherContainer: C2) -> Bool {

// 检查两个Container的元素个数是否相同

if someContainer.count != anotherContainer.count {

return false

}

// 检查两个Container相应位置的元素彼此是否相等

for i in 0..<someContainer.count {

if someContainer[i] != anotherContainer[i] {

return false

}

}

// 如果所有元素检查都相同则返回true

return true

}


var stackOfStrings2 = Stack2<String>()

stackOfStrings2.push("uno")

stackOfStrings2.push("dos")

stackOfStrings2.push("tres")


var arrayOfStrings2 = ["uno","dos","tres"]


//if allItemsMatch(stackOfStrings2,arrayOfStrings2) {

// print("All items match.")

//} else {

// print("Not all items match.")

//}

// 输出 "All items match."

//上面的例子创建一个 Stack 单例来存储 String,然后压了三个字符串进栈。这个例子也创建了一个 Array ,并初始化包含三个同栈里一样的原始字符串。即便栈和数组是不同的类型,但它们都遵循 Container ,而且它们都包含同样的类型值。因此你可以调用 allItemsMatch(_:_:) 函数,用这两个容器作为它的参数。在 上面的例子中,allItemsMatch(_:_:) 函数正确的显示了这两个容器的所有元素都是相互匹配的。

原文链接:https://www.f2er.com/swift/324991.html

猜你在找的Swift相关文章