先看一下Swift标准库中对CustomStringConvertible
协议的定义
public protocol CustomStringConvertible { /// A textual representation of this instance. /// /// Calling this property directly is discouraged. Instead, convert an /// instance of any type to a string by using the `String(describing:)` /// initializer. This initializer works with any type, and uses the custom /// `description` property for types that conform to /// `CustomStringConvertible`: /// /// struct Point: CustomStringConvertible { /// let x: Int, y: Int /// /// var description: String { /// return "(\(x), \(y))" /// } /// } /// /// let p = Point(x: 21, y: 30) /// let s = String(describing: p) /// print(s) /// // Prints "(21, 30)" /// /// The conversion of `p` to a string in the assignment to `s` uses the /// `Point` type"s `description` property. var description: String { get }}
从声明中我们可以看到协议中只包含了一个 description
的只读属性 ,而且通过协议命名也可以窥探到它的作用 Custom+String+Convertible (所作用的类型去自定义String的转换)
(资料图片仅供参考)
实现CustomStringConvertible
协议类似于在Objective-C中重写description
方法, 可用于:
如标准库中给的示例,拿出来分析一下:
struct Point: CustomStringConvertible { let x: Int, y: Int var description: String { return "(\(x), \(y))" }}let p = Point(x: 21, y: 30)let s = String(describing: p)print(s)// Prints "(21, 30)"
上例中结构体Point 实现了CustomStringConvertible协议, 完成了description属性的实现, 返回自定义字符串 "((x), (y))"。 接着使用String类型的
String(describing: p )
初始化方法完成了 Point结构体转成指定String类型格式的转换。
通过上面的介绍,我们基本上了解了CustomStringConvertible协议的用法, 接下来介绍几种使用场景。
二、使用场景1. 整型类型的枚举使用首先要知道的是 -- 在Swift中可以实现协议的类型有
结构体
、类
、枚举
。 也就是说只有结构体、 类、 枚举等类型都可以实现CustomStringConvertible协议
enum AudioStatus: Int {case stopped = 0, playing, recording, interruptionPlaying, interruptionRecording}
如果在使用枚举时,除了需要访问枚举的整型值
外,还需要可以方便的输出每个枚举对应的字符串类型的状态。 那么在这种场景下,通过extension
扩展枚举,并实现CustomStringConvertible
协议将会很合适
extension AudioStatus : CustomStringConvertible { var description: String { switch self { case .stopped: return "Audio: Stopped" case .playing: return "Audio: Playing" case .recording: return "Audio: Recording" case .interruptionPlaying: return "Audio: interruptionPlaying" case .interruptionRecording: return "Audio: interruptionRecording" } }}
使用:
let status:AudioStatus = .stoppedlet audioName = String(describing:status) //取整型枚举对应的 字符串值print(“audioName:\(audioName)”)
2. Class类型的使用定义一个类的话, 当我们使用print 时候并不会输出类中的变量
class Wheel { var spokes: Int = 0 var diameter: Double = 0.0 init(spokes:Int = 32,diameter:Double = 26.0) { self.spokes = spokes self.diameter = diameter } func removeSpokes() { spokes = spokes > 0 ? spokes-- : spokes }}var wheel = Wheel(spokes: 36,diameter: 29)print(wheel)/** * "Wheel\n" */
如果想要改变 print 的输出结果,我们需要让类遵守这个协议,最好用 extension扩展
extension Wheel: CustomStringConvertible { var description: String { return "wheel has \(spokes) spokes" }}var wheel = Wheel(spokes: 36,diameter: 29)print(wheel)/** * "wheel has 36 spokes\n" */
如果想了解更多内容,可以参见专栏 《ios开发你需要知道的》
Copyright @ 2015-2022 IT时代网版权所有 备案号: 沪ICP备2022005074号-4 联系邮箱:58 55 97 3@qq.com