Swift泛型协议的N种用法
They said "you should learn a new language every year," so I learned Swift. Now I learn a new language every two weeks!
这个笑话绝对是我看过的Swift被黑的最惨的一次!所以今天我们来学习一下Swift的泛型。
Swift的泛型有点奇怪,针对Class和Function,都是通过<Type>来定义,和C#一摸一样,同样也有where关键字进行约束。
func swapTwoValues<T>(inout a: T, inout _ b: T) {
let temporaryA = a
a = b
b = temporaryA
}
class CanPrintBase<T> {
func PrintType(output: T) -> Void {}
}
但是面对Interface,也就是Swift里的Protocol,需要使用associatedtype关键字来定义泛型:
protocol CanPrint {
associatedtype E
func PrintType(output: E) -> Void
}
那要怎么去实现这个接口呢?通常是这样子的:
class TypePrinter0 : CanPrint{
typealias E = String
func PrintType(output: E) {
print(type(of:output))
}
}
let print0 = TypePrinter0()
print0.PrintType(output: "String Type")
然后就会在output窗口打印“String”。
阿西吧!这么奇怪的语法简直不能忍!就不能用<Type>来写吗?
曲线救国的话,我们可以考虑模拟一个抽象类class CanPrintBase<T>,通过继承来实现同样的效果:
class TypePrinter3: CanPrintBase<String>{
override func PrintType(output: String){
print(type(of:output))
}
}
let print3 = TypePrinter3()
print3.PrintType(output: "String Type")
那么我们像C#一样直接在类定义的时候通过占位符的方式可以嘛?
//This one cannot work!
class TypePrinter1<E: String> : CanPrint{
func PrintType(output: E) {
print(output)
}
}
错误提示为:Inheritance from non-protocol, non-class type 'String'。也就是说如果是class类型的话就可以:
public class SomeType {}
class TypePrinter2<E: SomeType> : CanPrint{
func PrintType(output: E) {
print(output)
}
}
let print2 = TypePrinter2()
print2.PrintType(output: SomeType())
反之我们也可以写成这样:
class TypePrinter5 : CanPrint{
typealias E = SomeType
func PrintType(output: E) {
print(output)
}
}
let print5 = TypePrinter5();
print(type(of: print5))
print(type(of: print2))
将类型打印出来的话,分别是TypePrinter5和TypePrinter2<SomeType>,也就是说这两种写法得到的类型是完全不一样的。
呵呵也是蛮妖的嘛,还可以把类型的具体定义留到使用时再声明:
class TypePrinter4<E> : CanPrint{
func PrintType(output: E) {
print(output)
}
}
let print4 = TypePrinter4<SomeType>()
print4.PrintType(output: SomeType())
let print6 = TypePrinter4<String>()
print6.PrintType(output: "I am a String")
这一点又和C#傻傻分不清楚了。
本篇实在是蛮无聊的纠缠与Swift泛型协议的语法,如孔乙己般尝试了回字的N种写法。至于为什么Swift要这么设计,我们下一篇可以尝试和C#对比看看。
GitHub:
https://github.com/manupstairs/LearnSwift/tree/master/GenericProtocolTest
Swift泛型协议的N种用法的更多相关文章
- swift闭包的另一种用法
这不是教程. 当你碰到函数参数需要传递一个闭包(closure)时,一般是可以直接这么传递的(假定无返回): // 教程一般教你在参数位置传递closure: someMethod(arg1, arg ...
- swift 当协议遇见了泛型
由于泛型比较简单,并没有单独拿出来介绍!我们在定义函数的时候,有时候只是由于参数或者返回值类型不同,而具体的实现过程是一模一样的,这个时候我们就可以定义泛型函数而使可以传入不同的参数类型: func ...
- iOS -Swift 3.0 -for(循环语句用法)
// // ViewController.swift // Swift-循环语句 // // Created by luorende on 16/12/08. // Copyright © 2016年 ...
- .NET(c#)new关键字的三种用法
前几天去家公司面试,有一道这样的题:写出c#中new关键字的三种用法,思前想后挖空心思也只想出了两种用法,回来查了下msdn,还真是有第三种用法:用于在泛型声明中约束可能用作类型参数的参数的类型,这是 ...
- (转载)OC学习篇之---协议的概念和用法
在前一篇文章中我们介绍了OC中类的延展,这一篇文章我们在来看一下OC中协议的概念以及用法,协议也是OC中的一个重点,Foundation框架以及我们后面在写代码都会用到. OC中的协议就是相当于Jav ...
- NEW关键字的三种用法
最近面试中有一道题是写new关键字的几种用法,想了下写下我知道的两种用法 第一种 创建对象.调用构造函数,这就不用讲了 ClassA A=new ClassA(); 第二种 是作为修饰符,显示隐藏继 ...
- OC中协议的概念以及用法
OC中协议的概念以及用法,协议也是OC中的一个重点,Foundation框架以及我们后面在写代码都会用到. OC中的协议就是相当于Java中的接口(抽象类),只不过OC中的名字更形象点,因为我们在学习 ...
- c# new关键字的三种用法
三种用法如下: 在 C# 中,new 关键字可用作运算符.修饰符或约束. 1)new 运算符:用于创建对象和调用构造函数. 2)new 修饰符:在用作修饰符时,new 关键字可以显式隐藏从基类继承的成 ...
- Linux下dmesg命令处理故障和收集系统信息的7种用法
目录: <syslog之一:Linux syslog日志系统详解> <syslog之二:syslog协议及rsyslog服务全解析> <syslog之三:建立Window ...
随机推荐
- Redis 队列操作
class Program { //版本2:使用Redis的客户端管理器(对象池) public static IRedisClientsManager redisClientManager = ne ...
- (转)解释一下SQLSERVER事务日志记录
本文转载自桦仔的博客http://www.cnblogs.com/lyhabc/archive/2013/07/16/3194220.html 解释一下SQLSERVER事务日志记录 大家知道在完整恢 ...
- Java实现敏感词过滤
敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...
- [安卓] 18、一个简单的例子做自定义动画按钮和自定义Actionbar
在做安卓UI的时候有时候需自定义具有动画效果的按钮或需要自定义一下actionbar~ 本节用一个简单的demo讲如何自定义具有动画效果的按钮,以及个性化的actionbar 下面是效果: 其中: △ ...
- ReactMix框架,让你实现一套js代码,基于ReactNative在H5,App都能完美跑起来,Write Once,Run Anywhere
ReactNative框架推出已经有一段时间了,相信很多小伙伴都在尝试实现Write Once, Run Anywhere的梦想,比如淘宝的ReactWeb等等,但是这些框架都局限于因为ReactNa ...
- SiteMesh3整合SpringMVC+FreeMarker
SiteMesh3配置 添加maven依赖 添加filter 配置servlet 添加sitemesh配置文件 decorator示例 SpringMVC.FreeMarker配置(404问题处理) ...
- webservice5
如何访问webservice . 三种方式我知道, 但是, 方式1 只说明了如何访问wsdl, 不知道如何调用,现在就是需要知道如何像下面url描述一样 , http get .post 方式调用ws ...
- Hibernate中对象的三个状态解析
Hibernate 将操作的对象分为三种状态: 1. 瞬时 (Transient )/临时状态/自由状态 持久 (Persistent) 脱管 (Detached) 瞬时对象特征: 第一.不处于 Se ...
- Oracle函数脚本记录
--内置函数 --聚合函数 返回单个值 '; --count()记录条数 select sum(degree) from score t; --sum(degree)求成绩总和 select avg( ...
- Fiddler实战深入研究(二)
Fiddler实战深入研究(二) 阅读目录 Fiddler不能捕获chrome的session的设置 理解数据包统计 请求重定向(AutoResponder) Composer选项卡 Filters选 ...