Macros 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及以下版本 这

Swift目前是否支持宏,或者将来是否计划添加支持?目前我正在分散:

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!
}