扩展阵列以便对自定义日志记录友好

时间:2017-07-29 21:41:32

标签: arrays swift logging protocols

我在以下代码中定义了Loggable协议,我希望我的应用中Array类型符合Element的任何Loggable都可以轻松转换为一个字符串。

//: Playground - noun: a place where people can play

import UIKit

protocol Loggable {
    var logDescription: String { get }
}

struct Node: CustomStringConvertible {
    let id: Int

    var description: String {
        return "node: \(self.id) \n"
    }
}

let node1 = Node(id: 1)
let node2 = Node(id: 2)

let nodes = [node1, node2]

print(nodes)

extension Array: Loggable where Element: Loggable {

    var logDescription: String {
        var message = ""
        for element in self {
            message += element.logDescription
        }
        return message
    }
}


struct Logger {
    static func log(item: Loggable) {
        print(item.logDescription)
    }
}


Logger.log(item: nodes)

不幸的是,我得到Extension of type 'Array' with constraints cannot have an inheritance clause。有没有办法完成我想要做的事情?

更广泛地说,我非常感谢使用Swift功能获得更清晰的日志消息的任何建议或链接。

1 个答案:

答案 0 :(得分:0)

你有正确的总体思路,但执行中有一些错误:

  1. 首先,您需要使Node(数组的元素)符合Loggable协议。数组本身并不需要符合,因为它只是Loggable个对象的容器

    struct Node: Loggable, CustomStringConvertible {
        let id: Int
    
        var description: String {
            return "node: \(self.id) \n"
        }
    
        var logDescription: String {
            return "logDescription"
        }
    }
    
  2. Logger的日志功能修改为通用函数,其约束条件是参数应符合Loggable协议

    struct Logger {
    
        static func log<T>(item: T) where T: Loggable {
            print(item.logDescription)
        }
    
        static func log<T>(items: [T]) where T: Loggable {
            for item in items {
                print(item.logDescription)
            }
        }
    
        // Bonus functional points
    
        // static func log<T>(items: [T]) where T: Loggable {
        //     items.forEach() { print($0.logDescription) }
        // }
    
    }
    
  3. 现在您可以按预期调用日志函数

    let node1 = Node(id: 1)
    let node2 = Node(id: 2)
    let nodes = [node1, node2]
    
    Logger.log(items: nodes)
    
  4. 您应该查看CustomDebugStringConvertible,因为它符合标准库中非常相似的功能。