français - Macros dans Swift?




twig symfony (5)

Est-ce que Swift supporte actuellement les macros, ou est-ce qu'il y a des plans pour ajouter du support? Actuellement, je suis en train de disperser:

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

Dans divers endroits tout au long de mon code.


Dans ce cas, vous devez ajouter une valeur par défaut pour les paramètres "macro".

Swift 2.2 et supérieur

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 et inférieur

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

C'est ce que fatalError fonctions fatalError et assert .

Il n'y a pas d'autres macros sauf la compilation conditionnelle déjà mentionnée dans une autre réponse.


Depuis XCode 7.3, les __FILE__ __FUNCTION__ __FILE__ __FUNCTION__ et __LINE__ sont devenues #function #file #function et #line respectivement.


Les docs Apple déclarent que:

Déclarez des macros simples en tant que constantes globales et traduisez des macros complexes en fonctions.

Vous pouvez toujours utiliser # if / # else / # endif - mais mon sentiment est qu'ils n'introduiront pas de fonctions macro, le langage n'en a tout simplement pas besoin.


Les macros sont mauvaises, mais parfois vous en avez juste besoin. Par exemple, j'ai

struct RegionEntity {
    var id: Int!
}

Et je veux placer des instances de cette structure à Set. Je dois donc le conformer au protocole Hashable.

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

public func ==(first: RegionEntity, second: RegionEntity) -> Bool {
    return first.id == second.id
}

Génial. Mais que se passe-t-il si j'ai des dizaines de structures et que la logique est la même? Peut-être que je peux déclarer un protocole et le conformer implicitement à Hashable. Allons vérifier:

protocol Indexable {
    var id: Int! { get }
}

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

func ==(first: Indexable, second: Indexable) -> Bool {
    return first.id == second.id
}

Eh bien, ça fonctionne. Et maintenant je vais conformer ma structure aux deux protocoles:

struct RegionEntity: Indexable, Hashable {
    var id: Int!
}

Nan. Je ne peux pas faire cela, car Equatable requiert == operator avec Self et il n'y a pas d'opérateur == pour RegionEntity. Swift me force à copier-coller le code de confirmation pour chaque structure et à changer le nom. Avec la macro, je pourrais le faire avec une seule ligne.


lastPathComponent besoin d'un NSURL , donc j'ai changé le code ci-dessus en ceci:

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