Makra w Swift?

Czy Swift obsługuje obecnie makra, czy też istnieją plany dodania wsparcia w przyszłości? Aktualnie rozrzucam:

Log.trace(nil, function: __FUNCTION__, file: __FILE__, line: __LINE__)
W różnych miejscach mojego kodu.
Author: Forge, 2014-06-09

7 answers

W tym przypadku należy dodać wartość domyślną dla parametrów "makro".

Swift 2.2 i wyższe

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 i niższe

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

Do tego służą funkcje fatalError i assert.

Nie ma innych makr poza kompilacją warunkową wspomnianą już w innej odpowiedzi.

 55
Author: Sulthan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-19 07:52:23

Dokumenty Apple stwierdzają, że:

Deklaruje proste makra jako stałe globalne i tłumaczy złożone makra na funkcje.

Nadal można używać # if / # else / # endif - ale mam wrażenie, że nie wprowadzą funkcji makr, język po prostu tego nie potrzebuje.

 17
Author: ColinE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-09 05:46:47

Od XCode 7.3, the __FILE__ __FUNCTION__ i __LINE__ stałe czasu kompilacji stały się ładniej wyglądające #file #function i #line odpowiednio.

 5
Author: glenc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-27 16:01:45

lastPathComponent potrzebuje NSURL, więc zmieniłem powyższy kod na ten:

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")
 3
Author: Alan Edmonds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-20 09:38:14

Oto zaktualizowana odpowiedź 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)]"
}

Przykład użycia:

LogW("Socket connection error: \(error)")
 2
Author: Daniel Ryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-04 23:57:37

Jest sposób na użycie makr w języku swift (ale to używane w połączeniu z objective c i swift)

Zadeklaruj swoje makra do Project-name-Bridging-Header.h

#define  YOUR_MACRO @"Description"

Lub utworzyć oddzielny plik nagłówkowy dla makr "macros.h"

Importuj ten nagłówek " makra.h " w Twoim pomostowym nagłówku.plik H..

Teraz po prostu zapisz swój projekt Twoje makra pojawią się w pliku swift ..

Jeśli nie chcesz zgłaszać kodu c w swoim projekcie swift... wystarczy utworzyć atrapę cocoa touch klas to stworzy nagłówek mostkowy, a następnie Użyj mojej drogi...

 -1
Author: abdul sathar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-14 11:32:28

Makra są złe, ale czasami po prostu ich potrzebujesz. Na przykład Mam

struct RegionEntity {
    var id: Int!
}

I chcę umieścić instancje tej struktury na Set. Więc muszę dostosować to do protokołu Hashable.

extension RegionEntity: Hashable {
    public var hashValue: Int {
        return id
    }
}

public func ==(first: RegionEntity, second: RegionEntity) -> Bool {
    return first.id == second.id
}
Świetnie. Ale co jeśli mam dziesiątki takich struktur i logika jest taka sama? Może mogę zadeklarować jakiś protokół i dostosować go do Hashable bezwarunkowo. Sprawdźmy:
protocol Indexable {
    var id: Int! { get }
}

extension Indexable {
    var hashValue: Int {
        return id
    }
}

func ==(first: Indexable, second: Indexable) -> Bool {
    return first.id == second.id
}
To działa. A teraz dostosuję swoją strukturę do obu protokołów:
struct RegionEntity: Indexable, Hashable {
    var id: Int!
}
Nie. Nie mogę. to, ponieważ równanie wymaga operatora = = z Self i nie ma operatora == dla RegionEntity. Swift zmusza mnie do kopiowania i wklejania kodu potwierdzającego dla każdej struktury i po prostu zmiany nazwy. Z makro mogłem to zrobić tylko jedną linią.
 -1
Author: Nikolai Ischuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-15 22:13:33