Swift 如何获得方法’;s定义类’;她叫什么名字?
我使用下面的代码来记录一些函数调用Swift 如何获得方法’;s定义类’;她叫什么名字?,swift,static-methods,Swift,Static Methods,我使用下面的代码来记录一些函数调用 func functionWasCalled(file: String = #file, function: String = #function) { print("Function \(function) of file \(file) was called.") } 当它的调用者是一个方法时,我希望调用functionwas也打印调用者所属类的名称。即使该方法是静态的。我不想将任何显式参数传递给functionWasCall
func functionWasCalled(file: String = #file, function: String = #function) {
print("Function \(function) of file \(file) was called.")
}
当它的调用者是一个方法时,我希望调用functionwas
也打印调用者所属类的名称。即使该方法是静态的。我不想将任何显式参数传递给functionWasCalled。我能做什么?尝试以下操作:
String(describing: self)
就像这里:
class Foo {
func test () {
print(String(describing: self))
}
}
let f = Foo()
f.test()
输出:
Foo
对于类名,可以使用
self.classForCoder
,对于文件名,也可以使用#fileID
func functionWasCalled(file: String = #file, function: String = #function, fileID: String = #fileID, callClass: AnyObject?) {
print("Function \(function) of file \(file) was called.")
print("File id", fileID)
print("Class is - ", callClass?.classForCoder ?? self.classForCoder)
}
我不相信你具体要求的是可能的。据我所知,除了所提供的#-文本之外,无法在调用者的上下文中隐式地计算某些内容 也就是说,如果您稍微修改一下语法,就可以得到想要的效果
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
。确保您的记录器是无状态的,这样就可以按需创建它们
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
,可以添加额外的记录器.init
,如下所示:
public init(for staticCaller: Any.Type) {
self.caller = "\(staticCaller)"
}
这将导致类型作为其自身而不是其元类型进行计算
如果您的记录器是有状态的,或者具有中心配置,或者在许多记录器可能存在问题的其他情况下,您应该将有状态的“引擎”部分与此前端分离。当self
可用时,您还可以将log
设置为惰性变量,或者在init
中对其进行初始化
在我的个人日志模块中,我还有一个名为
Log
(大写)的全局“root”记录器。这使得不想命名自己的函数(例如顶级函数或闭包)更容易.您能告诉我如何使用我提供的函数吗?这里使用self
很可能是不正确的,因为这个函数可能是在日志类或其他常见类中定义的。您想打印定义类名还是调用方类名?我相信会有一些混淆,人们会将其理解为打印调用函数所属的类的名称。您可能需要更清楚地说明您指的是调用方的类型。(我觉得这很清楚,但显然让很多人感到困惑。)这是否回答了你的问题?我很确定这个问题没有你想要的解决方法。您可以读取Thread.callStackSymbols,但即使您实现了Demanling,它在非符号化(发布)构建中也不太可能有用。在ObjC中,这是通过预处理器宏实现的,但它们在Swift中不存在,并且除了提供的特定#-文本外,无法在调用站点计算默认值。@RobNapier谢谢。希望现在好多了。如果不是,请告诉我callClass是什么?它是调用此函数的类。我不想显式地传递任何参数。对不起,我应该说清楚的。我对问题进行了编辑以反映这一点。您是否尝试了self.dynamicType
?我无法访问调用方的self。