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

时间:2016-04-29 02:10:46

标签: swift

我正在编写一个LogUtil类,它只是将参数传递给'print'函数,并提供额外信息,如“filename,line NO。”等。请参阅下面的代码。

但是,通常我们使用'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)
}

1 个答案:

答案 0 :(得分:2)

首先致电LogUtil.d("tag", "param1", "param2")。由于items参数声明为可变参数Any...,因此items中的局部变量d的类型为[Any],其值为["tag", "param1", "param2"]

然后d调用p,将自己的items作为p {{1}的第一个参数传递参数。由于items的{​​{1}}参数也是可变参数,p 可以items' s {{传递更多参数1}}。也就是说,d 可以调用p。它没有,但它可以。

由于items的{​​{1}}参数是可变参数dp(LogLevel.DEBUG, items: items, "more", "words")内的局部变量p也是items类型},其值为Any...。它是由一个元素组成的数组中的三个元素。

您需要做的是使items或某个新功能采用 - 变量p参数,然后从[Any]调用该参数所有其他可变函数。

此外,不推荐使用[["tag", "param1", "param2"]]p。如果您已升级到Xcode 7.3,则应使用新的itemsd特殊表单。

但是您仍有问题:__FILE____LINE___将返回使用内部函数#file 的文件和行。这可能不是你想要的。您可能想要程序调用{​​{1}}或#line或其他任何内容的文件和行。

为此,您将文件和行参数传递给#file(和其他函数),默认值为#linep。默认值将在呼叫网站上展开,因此您可以获得对di或其他任何内容的调用的文件和行号。

所以最终你需要一个知道如何获取d(只有一个级别的数组包装)并将其转换为空格分隔字符串的函数。以下是您的表现方式:

#file

请注意,#line 不是variadic ,因此它不会在其d周围添加另一个数组包装。

然后定义所有用户可见的函数以调用i函数:

[Any]

当你致电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 { String($0) }.joinWithSeparator(" ") print("\(level) - \(file)(\(line)): \(itemString)") } 时,输出看起来像你想要的那样:

log(level:file:line:items:)