• Swift CustomStringConvertible 协议的使用


    一、前言

    先看一下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方法, 可用于:

    • 自定义作用类型的print输出
    • 作用的类型可自定义转换成String

    如标准库中给的示例,拿出来分析一下:

    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协议的用法, 接下来介绍几种使用场景。

    首先要知道的是 -- 在Swift中可以实现协议的类型有 结构体枚举。 也就是说只有结构体、 类、 枚举等类型都可以实现CustomStringConvertible协议

    二、使用场景

    1. 整型类型的枚举使用

    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 = .stopped
    let 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开发你需要知道的》

  • 相关阅读:
    BI神器Power Query(26)-- 使用PQ实现表格多列转换(2/3)
    UE4 自定义组件编译成功,但是无法在添加到 Actor(Add to Actor) 中找到,无法拖动到 Actor 中附加到 Root 的解决方法
    vi/vim快速注释多行,vi添加删除多行注释#,vi批量注释,批量添加注释,批量删除注释,vi显示行号
    C-1练习题
    Excel文件损坏打不开怎么办?可用这三招解决!
    elasticsearch运维_分享两个自己整理的比较好用的elasticsearch脚本
    springboot学生成绩分析系统 java ssm
    人事管理软件为企业提供了哪些价值?
    微信小程序 java在线租房-房屋租赁系统springboot
    Spring RequestContextHolder
  • 原文地址:https://www.cnblogs.com/reyzhang/p/17340421.html