我有以下代码定义了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功能获得更清晰日志消息的任何建议或链接。

最佳答案

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


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

struct Node: Loggable, CustomStringConvertible {
    let id: Int

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

    var logDescription: String {
        return "logDescription"
    }
}

Logger的log函数修改为通用函数,并具有参数应符合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) }
    // }

}

现在您可以按预期方式调用日志功能

let node1 = Node(id: 1)
let node2 = Node(id: 2)
let nodes = [node1, node2]

Logger.log(items: nodes)





您应该查看CustomDebugStringConvertible,因为它实现了与标准库非常相似的功能。

关于arrays - 扩展数组以方便自定义日志记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45394328/

10-12 15:07