swift 将可变参数传递给“print”不会产生所需的输出

rta7y2nd  于 5个月前  发布在  Swift
关注(0)|答案(1)|浏览(87)

我正在写一个LogUtil类,它只是简单地传递参数给'print'函数,并带有额外的信息,如“文件名,行号“等。
然而,通常当我们使用'print'函数输出时,会像这样:

print("param1", "param2")

字符串
它的产出是:

param1 param2


但是,使用我LogUtil进行日志记录,

LogUtil.d("tag", "param1", "param2"),


它的产出是:

D - /LogUtil.swift(44): [["tag", "param1", "param2"]]


我想输出原始的“print”样式:

D -/LogUtil.swift(44): tag param1 param2


如何解决这个问题?谢谢!

class func p(level: LogLevel, items: Any...) {
    //todo eric thread id
    //todo eric fileName is too long
    //todo eric loglevel control
    //todo eric outputs to file

    let filePath = __FILE__
    let lineNo = __LINE__
    print("\(getLogLevelDesc(level)) - \(filePath)(\(lineNo)):", items)

}

class func d(items: Any...) {
    return p(LogLevel.DEBUG, items: items)
}

class func i(items: Any...) {
    return p(LogLevel.INFO, items: items)
}

class func w(items: Any...) {
    return p(LogLevel.WARN, items: items)
}

class func e(items: Any...) {
    return p(LogLevel.ERROR, items: items)
}

class func fatal(items: Any...) {
    return p(LogLevel.FATAL, items: items)
}

ifmq2ha2

ifmq2ha21#

首先调用LogUtil.d("tag", "param1", "param2")。由于items参数被声明为可变参数Any...,因此d中的局部变量items的类型为[Any],值为["tag", "param1", "param2"]
然后d调用p,将自己的items作为pitems参数的第一个参数传递。由于pitems参数也是可变的,d * 可以 * 为pitems传递更多参数。也就是说,dcould 调用p(LogLevel.DEBUG, items: items, "more", "words")。它没有,但它可以。
由于pitems参数是可变参数Any...,因此p中的局部变量items也是[Any]类型,其值为[["tag", "param1", "param2"]]。它是一个包含三个元素的数组,位于一个元素的数组中。
你需要做的是使p,或一些新的函数,接受一个可变参数items,并从d和所有其他可变参数函数调用它。
此外,__FILE____LINE___已被弃用。如果您已升级到Xcode 7.3,则应使用新的#file#line特殊表单。
但是你仍然有一个问题:#file#line将返回它们在函数p中使用的文件和行。这可能不是你想要的。你可能想要程序调用di或其他东西的文件和行。
为此,您将文件和行参数传递给d(以及其他函数),默认值为#file#line。默认值将在调用站点展开,因此您将获得对di或其他函数的调用的文件和行号。
因此,最终你需要一个知道如何获取[Any](只有
一个**级别的数组 Package )并将其转换为空格分隔的字符串的函数。下面是你如何做到这一点:

struct LogUtil {

    enum LogLevel: String {
        case Debug
        case Info
        case Warning
        case Error
        case Fatal
    }

    // The low-level function that all the others call.
    private static func log(level level: LogLevel, file: String, line: Int, items: [Any]) {
        let itemString = items.map { “\($0)” }.joinWithSeparator(" ")
        print("\(level) - \(file)(\(line)): \(itemString)")
    }

字符串
注意,log(level:file:line:items:)非变元的,所以它不会在items周围添加另一个数组 Package 器。
然后定义所有用户可见的函数来调用log函数:

static func p(level: LogLevel, items: Any..., file: String = #file, line: Int = #line) {
        log(level: level, file: file, line: line, items: items)
    }

    static func d(items: Any..., file: String = #file, line: Int = #line) {
        log(level: .Debug, file: file, line: line, items: items)
    }

    static func i(items: Any..., file: String = #file, line: Int = #line) {
        log(level: .Info, file: file, line: line, items: items)
    }

    // other level-specific functions here...

}


当你调用LogUtil.d("tag", "foo", "bar")时,输出看起来像你想要的:

Debug - /var/folders/kn/<snip>/playground282.swift(33): tag foo bar

相关问题