三个关注点:1、形式;2、实现方式;3、使用方式;

一、基本形式:

形式:内部无泛型类型;

实现:只需指定类型和实现相应的功能即可;

使用:可以用在其他类型出现的任何地方;

protocol Response {

/// The task metrics containing the request / response statistics.

var _metrics: AnyObject? { get set }

mutating func add(_ metrics: AnyObject?)

}

Protocols as Types

Protocols don’t actually implement any functionality themselves. Nonetheless, any protocol you create will become a fully-fledged type for use in your code.

Because it’s a type, you can use a protocol in many places where other types are allowed, including:

  • As a parameter type or return type in a function, method, or initializer
  • As the type of a constant, variable, or property
  • As the type of items in an array, dictionary, or other container

实现类提供:函数的具体实现和存储变量;

对于变量,提供同名的存储变量即可;

二、普通泛型形式:

形式:内部无高阶类型,只包含普通泛型类型;

实现:只需指定类型和实现相应的功能即可;

使用:只能用作泛型类型的约束;

Protocol 'TransformType' can only be used as a generic constraint because it has Self or associated type requirements

public protocol TransformType {

associatedtype Object

associatedtype JSON

func transformFromJSON(_ value: Any?) -> Object?

func transformToJSON(_ value: Object?) -> JSON?

}

open class DataTransform: TransformType {

public typealias Object = Data

public typealias JSON = String

public init() {}

open func transformFromJSON(_ value: Any?) -> Data? {

guard let string = value as? String else{

return nil

}

return Data(base64Encoded: string)

}

open func transformToJSON(_ value: Data?) -> String? {

guard let data = value else{

return nil

}

return data.base64EncodedString()

}

}

三、monad形式:

形式:内部有包含泛型的高阶类型,包含类型构造器,是低阶类型与高阶类型相互转换和引用的桥梁;

使用:只能用作泛型类型的约束;

实现:

1、指定类型和实现相应;

2、对泛型本身进行扩展,实现构造类型变量的赋值;

3、对构造类型进行扩展,实现更多的功能;

4、实现为一个泛型类型?

public protocol ReactiveCompatible {

/// Extended type

associatedtype CompatibleType

/// Reactive extensions.

var rx: Reactive<CompatibleType> { get set }

}

extension ReactiveCompatible {

/// Reactive extensions.

public var rx: Reactive<Self> {

get {

return Reactive(self)

}

set {

// this enables using Reactive to "mutate" base object

}

}

}

extension NSObject: ReactiveCompatible { }

//—————————————————————

public final class Kingfisher<Base> {

public let base: Base

public init(_ base: Base) {

self.base = base

}

}

public protocol KingfisherCompatible {

associatedtype CompatibleType

var kf: CompatibleType { get }

}

public extension KingfisherCompatible {

public var kf: Kingfisher<Self> {

return Kingfisher(self)

}

}

extension Kingfisher where Base: Image {

fileprivate(set) var animatedImageData: Data? {

get {

return objc_getAssociatedObject(base, &animatedImageDataKey) as? Data

}

set {

objc_setAssociatedObject(base, &animatedImageDataKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)

}

}

}

四、内部实现依赖于其它协议

形式:关联类型有其它协议约束

实现:

1、关联类型协议类型的实现:

2、关联类型所定义的变量的构造;

3、主协议的实现(引用关联类型的协议的实现);

本质:先实现依赖的协议,然后实现本协议

使用:同二

public protocol Sequence {

associatedtype Iterator : IteratorProtocol

public func makeIterator() -> Self.Iterator

// ...

}

public protocol IteratorProtocol {

associatedtype Element

public mutating func next() -> Self.Element?

}

struct _Iterator: IteratorProtocol {

var children: Mirror.Children

init(obj: Any) {

children = Mirror(reflecting: obj).children

}

mutating func next() -> String? {

guard let child = children.popFirst() else { return nil }

return "\(child.label.wrapped) is \(child.value)"

}

}

protocol Sequencible: Sequence { }

extension Sequencible {

func makeIterator() -> _Iterator {

return _Iterator(obj: self)

}

}

swift protocol的几种形式的更多相关文章

  1. 代替jquery $.post 跨域提交数据的N种形式

    跨域的N种形式: 1.直接用jquery中$.getJSON进行跨域提交 优点:有返回值,可直接跨域: 缺点:数据量小: 提交方式:仅get (无$.postJSON) $.getJSON(" ...

  2. C++:一般情况下,设计函数的形参只需要两种形式

    C++:一般情况下,设计函数的形参只需要两种形式.一,是引用形参,例如 void function (int &p_para):二,是常量引用形参,例如 void function(const ...

  3. jquery插件的两种形式

    这里总结一下jquery插件的两种形式,一种是通过字面量的形式组织代码,另一种是通过构造函数的方式.下面就两种形式来分析俩个例子. 例子1: ;(function ($,window,document ...

  4. javascript面向对象系列第三篇——实现继承的3种形式

    × 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...

  5. 移动端App广告常见的10种形式

    什么是App广告?   App广告,或称In-App广告,是指智能手机和平板电脑这类移动设备中第三方应用程序内置广告,属于移动广告的子类别. App广告兴起得益于其载体—App的风行.平板电脑和大屏触 ...

  6. SQL 关于apply的两种形式cross apply 和 outer apply(转)

    转载链接:http://www.cnblogs.com/shuangnet/archive/2013/04/02/2995798.html apply有两种形式: cross apply 和 oute ...

  7. Struts2中Action接收参数的四种形式

    1.Struts2的Action接收参数的三种形式.      a. 使用Action的属性接收(直接在action中利用get方法来接收参数):                   login.js ...

  8. Node.js-提供了四种形式的定时器

    Node.js提供了四种形式的定时器 global.setTimeout(); //一次性定时器 global.setInterval(); //周期性定时器 global.nextTick(); / ...

  9. 参数传递的四种形式----- URL,超链接,js,form表单

    什么时候用GET,  查,删, 什么时候用POST,增,改  (特列:登陆用Post,因为不能让用户名和密码显示在URL上) 4种get传参方式 <html xmlns="http:/ ...

随机推荐

  1. 关于c++输出中的endl

    背景:本来这是一个很小的词,按理说写上一篇日志有点不值得,但是或许有一些东西,你也不知道,看看吧!         endl 是一个特殊值,称为操作符(manipulator),将它写入输出流时,具有 ...

  2. arm裸板驱动总结(makefile+lds链接脚本+裸板调试)

    在裸板2440中,当我们使用nand启动时,2440会自动将前4k字节复制到内部sram中,如下图所示: 然而此时的SDRAM.nandflash的控制时序等都还没初始化,所以我们就只能使用前0~40 ...

  3. String 字符串相加比较

    String 字符串相加 对比 public static void main(String[] args) { String a = "helloword"; final Str ...

  4. Vue: 生命周期, VueRouter

    Vue实例的生命周期: beforeCreate:   实例创建之前除标签外,所有的vue实例需要的数据,事件都不存在 created:  实例被创建之后,data和事件已经被解析到,el还没有找到 ...

  5. openstack-on-centos7之各组件服务

    认证服务keystone(安装和配置) 在配置 OpenStack 身份认证服务前,必须创建一个数据库和管理员令牌 [用数据库连接客户端以root用户连接到数据库服务] # mysql -u root ...

  6. JS之ClassName属性使用

    一.style与className属性的对比 在前面的style属性学习中,知道了通过style属性可以控制元素的样式,从而实现了行为层通过DOM的style属性去干预变现层显示的目地,但是这种就是不 ...

  7. [基础知识]PeopleSoft应用服务器上的进程含义

    1.PSAPPSRV PSAPPSRV作用是用来构建和报错HTML页面,运行peoplecode,处理消息和处理用户机器的sql请求.他还在用户机器最初登陆时候执行用户身份验证的任务. 2.PSSAM ...

  8. PeopleSoft面试题(服务器相关)

    如何配置app服务器与web服务器的负载均衡?请详细说明. App Server: 在配置App Server负载均衡时候,通过webserv目录下的configuration.properties文 ...

  9. IT的2017,面临数字生态系统新挑战,该怎么办?

    所谓数字生态系统,就是包含一系列基于标准,规模可变的硬件.软件.数字设备和服务,可系统地实现企业信息数字化,数据流通,以帮助企业提高运营效率. 随着越来越多的中国企业加入数字生态系统,中国CIO在技术 ...

  10. Nginx的性能优化

    1.优化worker进程个数: 在高并发.高访问量的WEB服务场景,需要事先启动更多的nginx进程,以保证快速响应并处理大量并发用户的请求,优化nginx进程个数的配置项就是,在nginx.conf ...