Swift 泛型简单应用

泛型从字面来理解就是一种泛指的类型,通过在类、方法、接口等指定泛型的类型,可以避免重写,达到重用的目的,而且可以通过泛型限制某些变量的类型,本文通过几个例子来阐述泛型在实际应用开发中的作用,并从以下几个方面介绍:

<h1>(1)泛型定义 </h1>

<h1>(2)泛型方法 </h1>

<h1>(3)泛型接口 </h1>

<h1>(4)泛型类 </h1>

<h2> 一、泛型定义 </h2>

通过尖括号指定泛型类型<T>,其中的T就是将要表示的类型被称为占位符,swift的泛型可以指定任意类型,Int,String等。

<h2> 二、泛型方法 </h2>

下面通过一个程序来介绍泛型方法,该方法用于交换两个相同类型的值。

1.交换两个Int类型的值

 func swapTest(inout a : Int , inout b: Int) {
    let c: Int = a
    a = b
    b = c
}
var a = 10
var b = 20
swapTest(&a, b: &b)

2.交换两个String类型的值

func swapTest(inout a : String , inout b: String) {
    let c: String = a
    a = b
    b = c
}
var a = "Tom"
var b = "Jerry"
swapTest(&a, b: &b)

此时就会发现问题,当每次新增一种类型时,就需要再写一个功能相同的函数,就会出现冗余,为了解决相同功能的函数在不同类型的对象间代码公用,那么我们需要使用泛型函数:

func swapTest<T>(inout a : T , inout b: T) {
    let c: T = a
    a = b
    b = c
}
var a = 10
var b = 20
swapTest(&a, b: &b)
var aString = "Tom"
var bString = "Jerry"
swapTest(&aString , &bString)

通过指定占位符来实现泛型函数,其中的T就为占位符,也就是说,函数在声明的时候并没有制定类型T,该类型需要在调用的时候指定,再看看此时函数的参数,也是通过占位符来限制a、b的类型相同。当调用函数swapTest时,函数会根据传入参数的类型确定T的实际类型。
当然泛型的占位符可以根据需要指定多个,例如:

func tuple<T , V>(a: T , b: V) -> (T , V) {
    let tu: (T , V) = (a , b)
    return tu
}

此方法根据指定两个泛型占位符,为调用处返回一个元胞数组。需要注意的是,此处虽然指定了两个泛型占位符,但是不代表T与V的类型一定不相同,可以进行如下调用tuple(10,20)。

<h2> 三、泛型接口(协议)</h2>

泛型接口与泛型方法和泛型类的定义略有不同,泛型接口在定义的时候并不直接通过尖括号声明,而是在接口内部通过associatedtype 并跟一个泛型占位符指定。如下所示

protocol CallBack {
    associatedtype Element
    var callBack: ((callData: Element!) -> Void)? { set get }
    func load(d: Element!)
}

此时Element就是一个占位符,泛型接口与普通的接口不一样,不可以用作变量的类型,只能用于对泛型进行约束,例如说不可以存在如下代码 var c = CallBack<Person>()。实现了该接口的类在进行load后会调用callBack将数据传回调用出。

<h2> 四、泛型类 </h2>

泛型类的定义如下所示:

class PrjObj: NSObject {    
     override init() {        super.init()    }   
     func test() {            }
}
class Test<T: PrjObj>: NSObject{
    var testObj: [T]!
    init(testObj: [T]) {
        super.init()
        self.testObj = testObj
    }
    func testObjFunc()  {
        for one in self.testObj {
            one.test()
        }
    }
}

通过声明Test类,该类的泛型占位符只接受PrjObj的子类,用于进行项目相关类的测试。只要是PrjObj的子类,就可以加入到数组中,进行测试。

<h2> 泛型的实际应用:</h2>

下面让我来模拟一个实际应用的场景,当网络请求成功后,将数据回调(仅仅是模拟)。
首先需要一个回调接口

protocol CallBack {
    associatedtype Element
    var callBack: ((callData: Element!) -> Void)? { set get }
    func load(d: Element!)
}

就像协议泛型所描述的,该协议的作用是限制实现了协议的类的功能,当位于服务层的网络请求响应成功后,会调用load方法,load方法的作用是调用callBack,将数据回溯至相关页面。

class Implement<T>: NSObject , CallBack {
   typealias Element = T
   var data: T!
   var callBack: ((callData: T!) -> Void)?
   func load(d: T!) {
       self.data = d
       self.callBack?(callData: self.data)
   }
}

Implement类为实现了CallBack接口的泛型类,并实现了load方法,load方法将设置data值,并将调用callBack。

class CarListener: Implement{    
    static let instance: CarListener = CarListener()
}
class PersonListener: Implement{
    static let instance: PersonListener = PersonListener()
}

声明两个Lisener的实现类,用来发送和接受相关类型的回调,PersonListener只负责用于Person类的回调,CarListener只负责Car类的回调

class DispatchReceive {
    var personListener: PersonListener = PersonListener.instance
    var carListener: CarListener = CarListener.instance
    func onMessage(person: Person!) {
    }
    func onMessage(car: Car!) -> Void {
    }
    init() {
        self.personListener.callBack = onMessage 
        self.carListener.callBack = onMessage
    }
}

DispatchReceive定义PersonListener 和 CarListener具体的回调方法,当相关的数据从服务器返回,会调用各自的onMessage方法,传入不同的参数。

class DispatchPost {
    // data from server
    func receivePersonFromServer() {
        PersonListener.instance.load(Person())
    }
    func receiveCarFromServer() {
        CarListener.instance.load(Car())
    }
}

DispatchPost 服务器返回数据,通过调用load方法将消息分发出去。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • object 变量可指向任何类的实例,这让你能够创建可对任何数据类型进程处理的类。然而,这种方法存在几个严重的问题...
    CarlDonitz阅读 908评论 0 5
  • 136.泛型 泛型代码让你可以写出灵活,可重用的函数和类型,它们可以使用任何类型,受你定义的需求的约束。你可以写出...
    无沣阅读 1,452评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 2017-11-15 M-5形象第7篇原创日记 M-5是日记星球299号星宝宝,M-5正在参加日记星球第11期蜕变...
    周琼辉阅读 498评论 3 5
  • 有那么一瞬间 我感觉迷失了自己 有意讨好 却适得其反 甚至开始怀疑人生 有些话 一旦说出来 真的很伤人 反过来想想...
    牛牛妈妈阅读 191评论 0 0