前端之家收集整理的这篇文章主要介绍了
swift学习笔记之泛型,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
/** * 泛型概览 在强类型语言中,你需要去定义诸如addInts,addFloats,addDoubles 等方法来正确地处理参数及返回值。 许多编程语言已经解决了这个问题。例如,在C++中,使用Template来解决。而Swift,Java和C#则采用了泛型来解决这个问题。泛型 Swift中的数组和字典类型就是使用泛型的经典例子。 */
/** * 泛型(generic)可以使我们在程序代码中定义一些可变的部分,在运行的时候指定。使用泛型可以最大限度地重用代码、保护类型的安全以及提高性能。在Swift集合类中,已经采用了泛型。 一、一个问题的思考 怎样定义一个函数来判断两个参数是否相等呢? 相比Object-C,Swift中的数组和字典都是类型安全的。一个Int型数组只可以保存Int而不可以保存String。这意味着你不用再查看文档啦,编译器就可以帮你做类型检查,然后你就就快可以愉快地coding了! 例如,在Object-C的UIKit中, 在自定义的View里面处理触摸事件可以这么写: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; 上述方法里面的set只可以保存UITouch实例, 因为文档里面就是这么说的。由于这个集合里面可以放任何对象,所以你需要在代码里面进行类型转换,也就是说把touches里面的对象转为UITouch对象。 当前Swift的标准库里面没有定义集合对象,但是你可以使用数组来代替集合对象,你可以用swift重写上面的代码: func touchesBegan(touches: [UITouch]!,withEvent event: UIEvent!) 上面的代码明确告诉你 touches数组只可以包含 UITouch实例, 否则编译器就会报异常。这样一来,你就再不用去做那烦人的类型转换了,因为编译器给你做了类型安全检查,保证数组里面只允许有 UITouch对象。 简要说来,泛型为类提供了一个类型参数。所有的数组都有相同的作用,即按顺序储存变量的数值,泛型数组除了多了一个类型参数之外,没有其他的不同之处。或许这样想更容易理解:你将要应用在数组上的各种算法和储存的数值类型无关,因此这些算法对于泛型数组和非泛型数组都适用。 */
func isEqualsInt(a:Int,b:Int) -> Bool {
return (a == b)
}
func isEqualsDouble(a:Double,b:Double) -> Bool {
return (a == b)
}
func isEqualsString(a:String,b:String) -> Bool {
return (a == b)
}
/** * 以上我们分别对3种不同的类型进行了比较,定义了类似的3个函数。那么我们是否可以定义1个函数能够比较3种不同的类型呢?如果isEqualsInt、isEqualsDouble和isEqualsString这3个函数名字后面的Int、Double和String是可变的,那么这些可变部分是与参数类型关联的。 */
/** 它们必须遵守Comparable协议实现类型。Comparable协议表示可比较的,在Swift中,基本数据类型以及字符串都是遵守Comparable协议的。 */
func isEquals<T: Comparable>(a: T,b: T) -> Bool {
return (a == b)
}
/** * 我们需要在T占位符后面添加冒号和协议类型,这种表示方式被称为泛型约束,它能够替换T的类型。在本例中,T的类型必须遵守Comparable协议的具体类。 */
let n1 = 200
let n2 = 100
print(isEquals(n1,b: n2))
let s1 = "ABC1"
let s2 = "ABC1"
print(isEquals(s1,b: s2))
struct IntStack {
var items = [Int]()
mutating func push(item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
}
/** * 这个结构体在栈中使用一个Array性质的items存储值。Stack提供两个方法:push和pop,从栈中压进一个值和移除一个值。这些方法标记为可变的,因为它们需要修改(或转换)结构体的items数组。 上面所展现的IntStack类型只能用于Int值,不过,其对于定义一个泛型Stack类(可以处理任何类型值的栈)是非常有用的。 */
struct TStack<T> {
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
/** * T代替了实际Int类型。这种类型参数包含在一对尖括号里(<T>),紧随在结构体名字后面。 T定义了一个名为“某种类型T”的节点提供给后来用。这种将来类型可以在结构体的定义里任何地方表示为“T”。在这种情况下,T在如下三个地方被用作节点: 创建一个名为items的属性,使用空的T类型值数组对其进行初始化; 指定一个包含一个参数名为item的push方法,该参数必须是T类型; 指定一个pop方法的返回值,该返回值将是一个T类型值。 */
/** * 当创建一个新单例并初始化时, 通过用一对紧随在类型名后的尖括号里写出实际指定栈用到类型,创建一个Stack实例,同创建Array和Dictionary一样: */
var stackOfStrings = TStack<String>()
stackOfStrings.push("uno")
stackOfStrings.push("dos")
stackOfStrings.push("tres")
stackOfStrings.push("cuatro")