395,Swift中的enum的协议(面试点:可以添加计算属性,不可以添加存储属性,mutating 可以改变自身枚举值,可以为枚举扩展extension,可以使用关联值的方法,来实现计算属性:...

协议(Protocols)

我已经提及了structsenums之间的相似性。除了附加方法的能力之外,Swift也允许你在枚举中使用协议(Protocols)协议扩展(Protocol Extension)

Swift协议定义一个接口或类型以供其他数据结构来遵循。enum当然也不例外。我们先从Swift标准库中的一个例子开始.

CustomStringConvertible是一个以打印为目的的自定义格式化输出的类型。

protocol CustomStringConvertible {
  var description: String { get }
}

该协议只有一个要求,即一个只读(getter)类型的字符串(String类型)。我们可以很容易为enum实现这个协议。

一些协议的实现可能需要根据内部状态来相应处理要求。例如定义一个管理银行账号的协议。

protocol AccountCompatible {
  var remainingFunds: Int { get }
  mutating func addFunds(amount: Int) throws
  mutating func removeFunds(amount: Int) throws
}

你也许会简单地拿struct实现这个协议,但是考虑应用的上下文,enum是一个更明智的处理方法。不过你无法添加一个存储属性到enum中,就像var remainingFuns:Int。那么你会如何构造呢?答案灰常简单,你可以使用关联值完美解决:

enum Account {
  case Empty
  case Funds(remaining: Int)

  enum Error: ErrorType {
    case Overdraft(amount: Int)
  }

  var remainingFunds: Int {
    switch self {
    case Empty: return 0
    case Funds(let remaining): return remaining
    }
  }
}

为了保持代码清爽,我们可以在enum的协议扩展(protocl extension)中定义必须的协议函数:

extension Account: AccountCompatible {

  mutating func addFunds(amount: Int) throws {
    var newAmount = amount
    if case let .Funds(remaining) = self {
      newAmount += remaining
    }
    if newAmount < 0 {
      throw Error.Overdraft(amount: -newAmount)
    } else if newAmount == 0 {
      self = .Empty
    } else {
      self = .Funds(remaining: newAmount)
    }
  }

  mutating func removeFunds(amount: Int) throws {
    try self.addFunds(amount * -1)
  }

}
var account = Account.Funds(remaining: 20)
print("add: ", try? account.addFunds(10))
print ("remove 1: ", try? account.removeFunds(15))
print ("remove 2: ", try? account.removeFunds(55))
// prints:
// : add:  Optional(())
// : remove 1:  Optional(())
// : remove 2:  nil

正如你所看见的,我们通过将值存储到enum cases中实现了协议所有要求项。如此做法还有一个妙不可言的地方:现在整个代码基础上你只需要一个模式匹配就能测试空账号输入的情况。你不需要关心剩余资金是否等于零。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 前言 和switch语句类似,Swift中的枚举乍看之下更像是C语言中枚举的进阶版本,即允许你定义一种类型,用于表...
    6ffd6634d577阅读 1,398评论 0 4
  • 原文戳我这个教程要求Xcode7和Swift2,在这里还是测试版,大家可以去下载最新的.在wwdc2015,发布了...
    iDeveloper阅读 270评论 0 0
  • 本文参考了Swift2.2与3.0的语法,在少数地方添加了自我理解与示例. 协议(Protocols) proto...
    果啤阅读 934评论 0 1
  • 协议规定了用来实现某一特定功能所必需的方法和属性。 任意能够满足协议要求的类型被称为遵循(conform)这个协议...
    零度_不结冰阅读 494评论 0 0
  • 1.Swift中的Protocol 什么是Protocol? Protocol是Swift中的一种自定义类型,可以...
    枫叶1234阅读 1,535评论 1 3

友情链接更多精彩内容