我在以下代码中定义了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功能获得更清晰的日志消息的任何建议或链接。
答案 0 :(得分:0)
你有正确的总体思路,但执行中有一些错误:
首先,您需要使Node
(数组的元素)符合Loggable
协议。数组本身并不需要符合,因为它只是Loggable
个对象的容器
struct Node: Loggable, CustomStringConvertible {
let id: Int
var description: String {
return "node: \(self.id) \n"
}
var logDescription: String {
return "logDescription"
}
}
将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) }
// }
}
现在您可以按预期调用日志函数
let node1 = Node(id: 1)
let node2 = Node(id: 2)
let nodes = [node1, node2]
Logger.log(items: nodes)
您应该查看CustomDebugStringConvertible,因为它符合标准库中非常相似的功能。