Подтвердить что ты не робот

Макросы в Swift?

Поддерживает ли Swift в настоящее время макросы или планируют ли добавить поддержку? В настоящее время я рассеиваю:

Log.trace(nil, function: __FUNCTION__, file: __FILE__, line: __LINE__)

В разных местах моего кода.

4b9b3361

Ответ 1

В этом случае вы должны добавить значение по умолчанию для параметров макроса.

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.

Нет других макросов, кроме условной компиляции, уже упомянутой в другом ответе.

Ответ 2

Apple docs утверждают, что:

Объявить простые макросы как глобальные константы и перевести сложные макросы в функции.

Вы все еще можете использовать # if/# else/# endif, но я чувствую, что они не будут вводить макрофункции, язык просто не нужен.

Ответ 3

Так как XCode 7.3, константы времени компиляции __FILE__ __FUNCTION__ и __LINE__ стали более привлекательными #file #function и #line соответственно.

Ответ 4

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")

Ответ 5

Вот обновленный ответ 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)")

Ответ 6

Макросы являются злыми, но иногда они вам просто нужны. Например, у меня есть

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
}

Великий. Но что, если у меня есть десятки таких структур и логика одна и та же? Может быть, я могу объявить какой-то протокол и не согласую его с 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!
}

Неа. Я не могу этого сделать, потому что Equatable требует == operator с Self, а для RegionEntity нет оператора ==. Swift заставляет меня копировать код подтверждения для каждой структуры и просто менять имя. С помощью макроса я мог бы сделать это только с одной строкой.

Ответ 7

Существует способ использования макросов в swift (но это используется в Mixed of c и swift)

объявить свои макросы в Project-name-Bridging-Header.h

#define  YOUR_MACRO @"Description"

или создать отдельный файл заголовка для макросов "macros.h"

импортируйте этот заголовок "macros.h" в файл Bridging-Header.h.

теперь просто сохраните свой проект, ваши макросы попадут в быстрый файл.

если вы не хотите, чтобы объектный код c в вашем быстром проекте... просто создайте манекен cocoa сенсорные классы, он создаст заголовок моста, а затем воспользуется моим способом...