Macros Swift中的宏?
Swift目前是否支持宏,或者将来是否计划添加支持?目前我正在分散:Macros Swift中的宏?,macros,swift,Macros,Swift,Swift目前是否支持宏,或者将来是否计划添加支持?目前我正在分散: Log.trace(nil, function: __FUNCTION__, file: __FILE__, line: __LINE__) 在我的代码中的各个地方。以下状态: 将简单宏声明为全局常量,并将复杂宏转换为函数 您仍然可以使用#if/#else/#endif-但我的感觉是它们不会引入宏函数,语言根本不需要它。在这种情况下,您应该为“宏”参数添加默认值 Swift 2.2及更高版本 Swift 2.1及以下版本 这
Log.trace(nil, function: __FUNCTION__, file: __FILE__, line: __LINE__)
在我的代码中的各个地方。以下状态:
将简单宏声明为全局常量,并将复杂宏转换为函数
您仍然可以使用#if/#else/#endif-但我的感觉是它们不会引入宏函数,语言根本不需要它。在这种情况下,您应该为“宏”参数添加默认值 Swift 2.2及更高版本 Swift 2.1及以下版本 这就是
fatalError
和assert
函数所做的
除了另一个答案中已经提到的条件编译之外,没有其他宏。
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)")
自XCode 7.3以来,
\uuuuuuuuu文件
\uuuuu函数
和\uuuuu行
编译时间常数分别成为了外观更好的\uuuuuuuuuuuuuuuuuuuuuuu文件
函数和\u35;行
。在swift上使用宏是有办法的(但这是在目标c和swift混合使用的)
将宏声明到项目名称桥接头.h
#define YOUR_MACRO @"Description"
或者为宏创建单独的头文件“macros.h”
将此标头“macros.h”导入到桥接标头.h文件中
现在只需保存您的项目,您的宏将以swift文件的形式出现
如果你不想在你的swift项目中反对c代码。。。只需创建虚拟cocoa touch类,它将创建桥接头,然后使用我的方式…宏是邪恶的,但有时您只需要它们。例如,我有
struct RegionEntity {
var id: Int!
}
我想设置这个结构的实例。所以我必须使它符合哈希协议
extension RegionEntity: Hashable {
public var hashValue: Int {
return id
}
}
public func ==(first: RegionEntity, second: RegionEntity) -> Bool {
return first.id == second.id
}
太好了。但是如果我有几十个这样的结构,并且逻辑是相同的呢?也许我可以声明一些协议并隐式地将其与Hashable一致。让我们检查一下:
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!
}
没有。我不能这样做,因为equalable需要带有Self的==运算符,而RegionEntity没有==运算符。
Swift强制我复制每个结构的粘贴确认代码,只需更改名称。有了宏,我只需要一行就可以做到这一点。对于在同一个文件中编译iOS和OS X非常有用的预处理器宏如何?@adib the#如果
风格的宏可以工作,并且非常适合这种任务“语言根本不需要它”。。。我在某个地方的文档中看到过这一点。我从Java迁移到C的经验强烈表明,一种没有像样的预处理器的语言迟早会产生冗长的表单。@随着注释的引入和APT的成熟,我不再缺少Java中的宏。swift有什么可比性吗?swift似乎有注释(@objc
,@IBAction
,@IBOutlet
…)但似乎还没有一种方法让开发人员定义自己的。有趣的是,在调用方中对\uuuu函数\uuu
进行了评估context@BryanChen是的,我注意到assert
声明中的默认值,所以我做了一些实验。\uuuu FILE\uuuuu
将文件的整个路径存储到变量文件中。如果您需要整理控制台输出,您可以考虑使用<代码> \(文件.LasTebug组件)< /C> >而不是<代码> \(文件)
所以你只能得到swift文件本身的文件名。@Sulthan哦,我不得不恭敬地表示不同意。这当然不是完全无关的。在我打算的情况下,我需要最快的日志记录,而不影响触摸性能。大多数应用只记录业务逻辑?问题在我的书中,这是一种巧妙的过度杀伤力,但也不是一个真正的缺点。跟踪日志记录?非常有用。加上未来在服务器端…非常有用。不同的用例,不同的实现。不要做那种认为自己领域外的用例无关紧要的人。“此外,这与我们在这里讨论的调试日志是非常不同的用例。”有趣。在原始问题或您的答案中找不到。日志记录就是日志记录。此外:原始问题使用“Log.trace”,这对我来说通常是一个…tracelog.Perf有时很重要。如果您需要更快的日志记录,您可以使用我的提示。但不要争辩这是“无关的”。我很高兴一些答案添加了NSURL代码。也就是说,为什么不使用。例如,让className=url.lastPathComponent>文件
。这在复杂的宏上根本不起作用。您必须使用函数重新创建。我认为您需要将RegionEntity
与equalable
-协议相一致,并添加一些内容像extensionregionentity{static func==(lhs:RegionEntity,rhs:RegionEntity)->Bool{return lhs.id==rhs.id}}
这实际上并没有解决这个问题。
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!
}