我有以下代码定义了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/