Swift CustomStringConvertible 协议的使用

打印 上一主题 下一主题

主题 802|帖子 802|积分 2406

目录

一、前言

先看一下Swift标准库中对CustomStringConvertible协议的定义
  1. public protocol CustomStringConvertible {
  2.     /// A textual representation of this instance.
  3.     ///
  4.     /// Calling this property directly is discouraged. Instead, convert an
  5.     /// instance of any type to a string by using the `String(describing:)`
  6.     /// initializer. This initializer works with any type, and uses the custom
  7.     /// `description` property for types that conform to
  8.     /// `CustomStringConvertible`:
  9.     ///
  10.     ///    struct Point: CustomStringConvertible {
  11.     ///        let x: Int, y: Int
  12.     ///
  13.     ///        var description: String {
  14.     ///            return "(\(x), \(y))"
  15.     ///        }
  16.     ///    }
  17.     ///
  18.     ///    let p = Point(x: 21, y: 30)
  19.     ///    let s = String(describing: p)
  20.     ///    print(s)
  21.     ///    // Prints "(21, 30)"
  22.     ///
  23.     /// The conversion of `p` to a string in the assignment to `s` uses the
  24.     /// `Point` type's `description` property.
  25.     var description: String { get }
  26. }
复制代码
从声明中我们可以看到协议中只包含了一个 description的只读属性 ,而且通过协议命名也可以窥探到它的作用 Custom+String+Convertible (所作用的类型去自定义String的转换)
实现CustomStringConvertible协议类似于在Objective-C中重写description方法, 可用于:

  • 自定义作用类型的print输出
  • 作用的类型可自定义转换成String
如标准库中给的示例,拿出来分析一下:
  1. struct Point: CustomStringConvertible {
  2.     let x: Int, y: Int
  3.     var description: String {
  4.         return "(\(x), \(y))"
  5.     }
  6. }
  7. let p = Point(x: 21, y: 30)
  8. let s = String(describing: p)
  9. print(s)
  10. // Prints "(21, 30)"
复制代码
上例中结构体Point 实现了CustomStringConvertible协议, 完成了description属性的实现, 返回自定义字符串 "((x), (y))"。  接着使用String类型的  String(describing: p ) 初始化方法完成了 Point结构体转成指定String类型格式的转换。
通过上面的介绍,我们基本上了解了CustomStringConvertible协议的用法, 接下来介绍几种使用场景。
首先要知道的是 -- 在Swift中可以实现协议的类型有 结构体、 类、 枚举。  也就是说只有结构体、 类、 枚举等类型都可以实现CustomStringConvertible协议
二、使用场景

1. 整型类型的枚举使用
  1. enum AudioStatus: Int {
  2.         case stopped = 0, playing, recording, interruptionPlaying, interruptionRecording
  3. }
复制代码
如果在使用枚举时,除了需要访问枚举的整型值外,还需要可以方便的输出每个枚举对应的字符串类型的状态。 那么在这种场景下,通过extension扩展枚举,并实现CustomStringConvertible协议将会很合适
  1. extension AudioStatus : CustomStringConvertible {
  2.    
  3.     var description: String {
  4.         switch self  {
  5.         case .stopped:
  6.             return "Audio: Stopped"
  7.         case .playing:
  8.             return "Audio: Playing"
  9.         case .recording:
  10.             return "Audio: Recording"
  11.         case .interruptionPlaying:
  12.             return "Audio: interruptionPlaying"
  13.         case .interruptionRecording:
  14.             return "Audio: interruptionRecording"
  15.         }
  16.     }
  17. }
复制代码
使用:
  1. let status:AudioStatus = .stopped
  2. let audioName = String(describing:status)  //取整型枚举对应的 字符串值
  3. print(“audioName:\(audioName)”)
复制代码
2. Class类型的使用

定义一个类的话, 当我们使用print 时候并不会输出类中的变量
  1. class Wheel {
  2.     var spokes: Int = 0
  3.     var diameter: Double = 0.0
  4.    
  5.     init(spokes:Int = 32,diameter:Double = 26.0) {
  6.         self.spokes = spokes
  7.         self.diameter = diameter
  8.     }
  9.    
  10.     func removeSpokes() {
  11.         spokes = spokes > 0 ? spokes-- : spokes
  12.     }
  13. }
  14. var wheel = Wheel(spokes: 36,diameter: 29)
  15. print(wheel)
  16. /**
  17. *  "Wheel\n"
  18. */
复制代码
如果想要改变 print 的输出结果,我们需要让类遵守这个协议,最好用 extension扩展
  1. extension Wheel: CustomStringConvertible {
  2.     var description: String {
  3.         return "wheel has \(spokes) spokes"
  4.     }
  5. }
  6. var wheel = Wheel(spokes: 36,diameter: 29)
  7. print(wheel)
  8. /**
  9. *  "wheel has 36 spokes\n"
  10. */
复制代码
如果想了解更多内容,可以参见专栏 《ios开发你需要知道的》

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

石小疯

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表