Swift中的macros?
Swift目前是否支持macros,还是有未来计划添加支持? 目前我正在散射:
Log.trace(nil, function: __FUNCTION__, file: __FILE__, line: __LINE__)
在我的代码中的各个地方。
在这种情况下,您应该为“macros”参数添加一个默认值。
Swift 2.2及更高版本
func log(message: String, function: String = #function, file: String = #file, line: Int = #line) { print("Message \"\(message)\" (File: \(file), Function: \(function), Line: \(line))") } log("Some message")
Swift 2.1和更低
func log(message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__) { print("Message \"\(message)\" (File: \(file.lastPathComponent), Function: \(function), Line: \(line))") } log("Some message")
这是fatalError
和assert
函数的作用。
除了另一个答案中已经提到的条件编译之外,没有其他的macros。
苹果文档指出:
将简单的macros声明为全局常量,并将复杂的macros转换为函数。
你仍然可以使用#if /#else /#endif – 但我的感觉是他们不会引入macros函数,这个语言根本就不需要它。
由于XCode 7.3, __FUNCTION__
__FILE__
__FUNCTION__
和__LINE__
编译时常量分别变成了更好看的#file
和#line
。
lastPathComponent
需要一个NSURL
,所以我将上面的代码改为:
func log(message: String, function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__) { let url = NSURL(fileURLWithPath: file) print("Message \"\(message)\" (File: \(url.lastPathComponent ?? "?"), Function: \(function), Line: \(line))") } log("some message")
这是一个更新的Swift 2的答案。
func LogW(msg:String, function: String = #function, file: String = #file, line: Int = #line){ print("[WARNING]\(makeTag(function, file: file, line: line)) : \(msg)") } private func makeTag(function: String, file: String, line: Int) -> String{ let url = NSURL(fileURLWithPath: file) let className = url.lastPathComponent ?? file return "\(className) \(function)[\(line)]" }
使用示例:
LogW("Socket connection error: \(error)")
macros是邪恶的,但有时你只需要它们。 例如,我有
struct RegionEntity { var id: Int! }
我想把这个结构的实例放到Set中。 所以我必须遵守Hashable协议。
extension RegionEntity: Hashable { public var hashValue: Int { return id } } public func ==(first: RegionEntity, second: RegionEntity) -> Bool { return first.id == second.id }
大。 但是,如果我有几十个这样的结构,逻辑是一样的呢? 也许我可以声明一些协议,并将其隐式地符合Hasaps。 让我们检查:
protocol Indexable { var id: Int! { get } } extension Indexable { var hashValue: Int { return id } } func ==(first: Indexable, second: Indexable) -> Bool { return first.id == second.id }
那么,它的工作。 现在我要把我的结构符合两个协议:
struct RegionEntity: Indexable, Hashable { var id: Int! }
不。 我不能这样做,因为Equatable需要==运算符与自我和RegionEntity没有==运算符。 Swift迫使我复制粘贴每个结构的确认代码,只是改变名称。 用macros我可以做到只有一行。
有一种方法可以在swift上使用macros(但是这在混合的目标c和swift中使用)
将您的macros声明为Project-name-Bridging-Header.h
#define YOUR_MACRO @"Description"
或为macros创build单独的头文件"macros.h"
将此头文件“macros.h”导入到您的Bridging-Header.h文件中。
现在只需保存你的项目,你的macros就会在swift文件中出现。
如果你不想在你的swift项目上使用c代码,只要创build虚拟的cocoa触摸类,它将创build桥接头,然后使用我的方式…