如何获得方法的定义类的名称?

菲利普·安德烈·洛林(Philippe-AndréLorin)

我正在使用以下记录一些函数调用。

func functionWasCalled(file: String = #file, function: String = #function) {
    print("Function \(function) of file \(file) was called.")
}

当它的调用者是一个方法时,我functionWasCalled还要打印该调用者所属的类名称即使该方法是静态的。而且我不想将任何显式参数传递给functionWasCalled。我能做些什么?

罗布·纳皮尔

我不认为您明确要求的是可能的。除了提供的#-literal之外,我无法知道在调用者的上下文中隐式评估某些内容。

就是说,如果您稍稍更改语法,就可以得到想要的效果。

public class Logger {
    public let caller: String

    public init(for caller: Any) {
        self.caller = "\(type(of: caller))"
    }

    public func info(_ message: String, file: String = #file, line: Int = #line, function: String = #function) {
        print("Function \(function) of \(caller) in file \(file) was called.")
    }
}

现在,在使用记录器的对象中,他们只需要使用一致的名称(例如)创建自己的对象即可log确保您的Logger是无状态的,因此可以按需创建它们。

class MyLoggingThing {
    var log: Logger { Logger(for: self) }

    func doSomething() {
        log.info("Let's do this")
    }
}

// Function doSomething() of MyLoggingThing in file MyPlayground.playground was called.

您可以通过扩展使它更好一点,并处理静态方法:

protocol Logging {}
extension Logging {
    static var log: Logger { Logger(for: self) }
    var log: Logger { Logger(for: self) }
}

class MyLoggingThing: Logging {
    static func doSomethingStatic() {
        log.info("Even static")
    }
    func doSomething() {
        log.info("Let's do this")
    }
}

请注意,静态方法会将类型显示为MyLoggingThing.Type这是好是坏,取决于您想要什么。如果您不喜欢多余的东西.Type,可以添加这样的额外Logger.init东西:

public init(for staticCaller: Any.Type) {
    self.caller = "\(staticCaller)"
}

这将导致将类型作为自身而不是作为其元类型来求值。

如果您的记录器是有状态的或具有中央配置,或者在其他情况下可能会出现许多记录器的问题,则应从此前端中拆分有状态的“引擎”部分。您还可以创建log一个惰性var或在可用init对其进行初始化self

在我的个人日志记录模块中,我还有一个全局的“ root”日志记录器,称为Log(具有大写字母)。这使得可能不想自己命名的函数(例如顶层函数或闭包)更加容易。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章