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 ...
随机推荐
- Replication的犄角旮旯(四)--关于事务复制的监控
<Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...
- NativeScript 也能开发桌面应用 (nativescript-dotnet-runtime)
自从看了NativeScript就甚是喜欢,心想要是也能开发桌面应用该多好.求人不如求己,开源组件很强大,差不多组装一下就行了,说干就干. Javascript 引擎用 Jint , 纯C#实现,集成 ...
- MicroPHP 2.2.0 发布
ver 2.2.0: 增加了: 1.$this->cache为最新的phpfastcache2.1,缓存功能更加强大,而且编写自己的缓存类非常容易. 2.自定义缓存类说明: ...
- JSON数据查询方法
在进行前端项目开发的时候时长会遇到JSON的数据查找问题,如何方便快速查找?这里推荐一个linqjs组件,项目主页参见http://linqjs.codeplex.com/ 查询对象 var json ...
- 如何参与一个 GitHub 开源项目?
最近一年开源项目特别的热,很多技术大会或论坛都以开源项目作为主题进行探讨,可见这是一种趋势.而Github作为开源项目的著名托管地,可谓无 人不知,越来越多的个人和公司纷纷加入到Github的大家族里 ...
- win7升级为Win10 10586版本,出现应用商店打不开的解决办法
把公司的win7升级为了win10,但是打开应用商店时是白的,什么都没有,过一会之后,会有提示信息. 报的错误是: 错误代码:0X80072ee2 最后,我的解决办法是: 首先,咱们返回到win10 ...
- 解决ng界面长表达式(ui-set)
本文来自网友sun shine的问题,问题如下: 您好, 我想求教一个问题. 在$scope中我的对象名字写的特别深, 在 html中我又多次用到了同一个对象, 对不对在 html中让它绑定到一个临时 ...
- .net 时间戳和日期互转
1.时间戳转日期 public static DateTime IntToDateTime(int timestamp) { ,,)).AddSeconds(timestamp); } 调用: ...
- Macaca-iOS入门那些事2
Macaca-iOS入门那些事2 一. 前言 上文<Macaca-iOS入门那些事>讲到Macaca环境部署及运行了第一个案例,本文将讲解其案例编写. 二. 测试案例解析 iOS案例:ma ...
- rewrite规则写法及nginx配置location总结
rewrite只能放在server{},location{},if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用. 例如http://seanlook.com/a/we/index.php ...