swift学习笔记之泛型

原创 2016年05月30日 11:00:03
//泛型函数,泛型枚举,泛型结构,泛型类,泛型约束,关联泛型


/**
*  泛型概览    

在强类型语言中,你需要去定义诸如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是可变的,那么这些可变部分是与参数类型关联的。
*/


//func isEquals<T>(a: T, b: T) -> Bool {
//    return (a == b) //运算符是否要重载
//}
/**
它们必须遵守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))
///


//--------------------------泛型栈---------------------------
//这里展示了如何写一个非泛型版本的栈,

//Int值型的栈:
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")

版权声明:版权所有,不得转载

相关文章推荐

Swift中的协议

Swift中的协议Swift中的常用协议EquatableEquatable 协议用于相等的比较,遵守这个协议后必须对==运算符进行重载。struct Record: Equatable { ...

Swift泛型和泛型函数

泛型(generic)可以使我们在程序代码中定义一些可变的部分,在运行的时候指定。使用泛型可以最大限度地重用代码、保护类型的安全以及提高性能。在Swift集合类中,已经采用了泛型。一、一个问题的思考怎...

The Swift Programming Language学习笔记(二十四)——泛型

泛型 泛型所解决的问题 泛型函数 类型参数 命名类型参数 泛型类型 扩展一个泛型类型 类型约束 类型约束语法 类型约束实践 关联类型 关联类型实践 通过扩展一个存在的类型来指定关联类型 where子句...

iOS学习笔记47-Swift(七)泛型

一、Swift泛型介绍泛型是为Swift编程灵活性的一种语法,在函数、枚举、结构体、类中都得到充分的应用,它的引入可以起到占位符的作用,当类型暂时不确定的,只有等到调用函数时才能确定具体类型的时候可以...

Swift学习笔记系列——(23)泛型

Swift学习笔记系列——(23)泛型

Swift学习笔记(十八)泛型

泛型 泛型代码可以让你写出根据自我需求定义、适用于任何类型的,灵活且可重用的函数和类型 泛型所解决的问题 定义一个swapTwoInts方法,用于交换两个int类型的值 一:swapTwoIn...

swift学习笔记(20)- 泛型

泛型函数泛型函数可以适用于任何类型,下面的 swapTwoValues(::) 函数是上面三个函数的泛型版本:func swapTwoValues(_ a: inout T, _ b: inout T...

Swift学习笔记(二十三)——Swift泛型初识

泛型的概念在Java中也是存在的,泛型可以使代码更为精炼,是对数据类型使用的一种优化。现在有一样的一个需求:写一个结构体,然后判断整型的是否相等。好,实现代码以及输出如下: 。      如果此时...

10. 泛型 Part 1 --- 学习笔记

 9. 多线程 Part 4 生产者及消费者模式 --- 学习笔记
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)