Recherche…


Syntaxe

  • macro "string" # short, chaîne de forme de macro
  • @macro_str "string" # forme de macro longue et régulière
  • macro`command`

Remarques

Les macros de chaînes de caractères ne sont pas aussi puissantes que les anciennes chaînes de caractères ordinaires - car l'interpolation doit être implémentée dans la logique de la macro, les macros de chaînes ne peuvent pas contenir de littéraux de chaîne du même délimiteur pour l'interpolation.

Par exemple, bien que

julia> "$("x")"
"x"

fonctionne, la forme de texte de macro de chaîne

julia> doc"$("x")"
ERROR: KeyError: key :x not found

est analysé de manière incorrecte. Cela peut être quelque peu atténué en utilisant des guillemets comme séparateur de chaîne externe;

julia> doc"""$("x")"""
"x"

fonctionne effectivement correctement.

Utiliser des macros de chaîne

Les macros de chaîne sont du sucre syntaxique pour certaines invocations de macros. L'analyseur développe la syntaxe comme

mymacro"my string"

dans

@mymacro_str "my string"

qui, comme tout autre appel de macro, est remplacé par l'expression que @mymacro_str macro @mymacro_str . La base Julia est fournie avec plusieurs macros de chaîne, telles que:

@b_str

Cette macro de chaîne construit des tableaux d' octets au lieu de chaînes . Le contenu de la chaîne, codé en UTF-8, sera utilisé comme tableau d'octets. Cela peut être utile pour l'interfaçage avec des API de bas niveau, dont beaucoup fonctionnent avec des tableaux d'octets au lieu de chaînes.

julia> b"Hello World!"
12-element Array{UInt8,1}:
 0x48
 0x65
 0x6c
 0x6c
 0x6f
 0x20
 0x57
 0x6f
 0x72
 0x6c
 0x64
 0x21

@big_str

Cette macro renvoie un BigInt ou un BigFloat analysé à partir de la chaîne fournie.

julia> big"1"
1

julia> big"1.0"
1.000000000000000000000000000000000000000000000000000000000000000000000000000000

Cette macro existe car big(0.1) ne se comporte pas comme on pouvait s’y attendre: le 0.1 est une approximation Float64 de true 0.1 ( 1//10 ), et la promotion de cette BigFloat à BigFloat conservera l’erreur d’approximation de Float64 . Utiliser la macro analysera 0.1 directement dans un BigFloat , réduisant ainsi l’erreur d’approximation.

julia> big(0.1)
1.000000000000000055511151231257827021181583404541015625000000000000000000000000e-01

julia> big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

@doc_str

Cette macro de chaîne Base.Markdown.MD objets Base.Markdown.MD , qui sont utilisés dans le système de documentation interne pour fournir une documentation en texte riche pour tout environnement. Ces objets MD se rendent bien dans un terminal:

documentation de démarquage terminal rend bien

et aussi dans un navigateur:

la documentation de démarquage du navigateur rend bien

@html_str

Cette macro de chaîne construit des littéraux de chaîne HTML, qui s'affichent bien dans un navigateur:

html string macro rendu bien dans un navigateur

@ip_str

Cette macro de chaîne construit des littéraux d'adresse IP. Il fonctionne avec IPv4 et IPv6:

julia> ip"127.0.0.1"
ip"127.0.0.1"

julia> ip"::"
ip"::"

@r_str

Cette macro de chaîne construit des littéraux Regex .

@s_str

Cette macro de chaîne construit des littéraux SubstitutionString , qui fonctionnent avec les littéraux Regex pour permettre une substitution textuelle plus avancée.

@text_str

Cette macro de chaîne est similaire dans l'esprit à @doc_str et @html_str , mais ne possède aucune fonctionnalité de formatage sophistiquée:

texte brut dans le navigateur

@v_str

Cette macro de chaîne construit des littéraux VersionNumber . Voir les numéros de version pour une description de ce qu'ils sont et comment les utiliser.

@MIME_str

Cette macro de chaîne construit les types singleton des types MIME. Par exemple, MIME"text/plain" est le type de MIME("text/plain") .

Symboles qui ne sont pas des identifiants légaux

Les symboles littéraux de Julia doivent être des identificateurs légaux. Cela marche:

julia> :cat
:cat

Mais cela ne fait pas:

julia> :2cat
ERROR: MethodError: no method matching *(::Int64, ::Base.#cat)
Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...) at operators.jl:288
  *{T<:Union{Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}}(::T<:Union{Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}, ::T<:Union{Int128,Int16,Int32,Int64,Int8,UInt128,UInt16,UInt32,UInt64,UInt8}) at int.jl:33
  *(::Real, ::Complex{Bool}) at complex.jl:180
  ...

Ce qui ressemble à un littéral de symbole ici est en fait analysé comme une multiplication implicite de :2 (qui est juste 2 ) et la fonction cat , qui ne fonctionne évidemment pas.

On peut utiliser

julia> Symbol("2cat")
Symbol("2cat")

pour contourner le problème.

Une macro de chaîne pourrait aider à rendre ceci plus concis. Si nous définissons la macro @sym_str :

macro sym_str(str)
    Meta.quot(Symbol(str))
end

alors on peut simplement faire

julia> sym"2cat"
Symbol("2cat")

pour créer des symboles qui ne sont pas des identifiants Julia valides.

Bien entendu, ces techniques peuvent également créer des symboles qui sont des identifiants Julia valides. Par exemple,

julia> sym"test"
:test

Implémentation de l'interpolation dans une macro de chaîne

Les macros de chaîne ne sont pas fournies avec des fonctions d' interpolation intégrées. Cependant, il est possible d'implémenter manuellement cette fonctionnalité. Notez qu'il n'est pas possible d'incorporer sans échapper les littéraux de chaîne qui ont le même délimiteur que la macro de chaîne environnante; c'est-à-dire que """ $("x") """ est possible, " $("x") " n'est pas. Au lieu de cela, cela doit être échappé comme " $(\"x\") " . Voir la section des remarques pour plus de détails sur cette limitation.

Il existe deux approches pour implémenter l'interpolation manuellement: implémenter l'analyse syntaxique manuellement ou demander à Julia d'effectuer l'analyse. La première approche est plus flexible, mais la seconde approche est plus facile.

Analyse manuelle

macro interp_str(s)
    components = []
    buf = IOBuffer(s)
    while !eof(buf)
        push!(components, rstrip(readuntil(buf, '$'), '$'))
        if !eof(buf)
            push!(components, parse(buf; greedy=false))
        end
    end
    quote
        string($(map(esc, components)...))
    end
end

Julia analyse

macro e_str(s)
    esc(parse("\"$(escape_string(s))\""))
end

Cette méthode échappe à la chaîne (mais notez que la escape_string n'échappe pas aux signes $ ) et la renvoie à l'analyseur syntaxique de Julia pour l'analyse. Echapper à la chaîne est nécessaire pour s'assurer que " et \ n'affecte pas l'analyse de la chaîne. L'expression résultante est une expression :string , qui peut être examinée et décomposée à des fins macro.

Macros de commande

0.6.0-dev

Dans Julia v0.6 et versions ultérieures, les macros de commandes sont prises en charge en plus des macros de chaîne standard. Une invocation de macro de commande comme

mymacro`xyz`

est analysé comme l'appel de macro

@mymacro_cmd "xyz"

Notez que cela est similaire aux macros de chaînes, sauf avec _cmd au lieu de _str .

Nous utilisons généralement des macros de commande pour le code, ce qui dans de nombreuses langues contient souvent " mais contient rarement ` , par exemple, il est assez facile de ré - écrire une version simple. Quasiquoting en utilisant des macros de commande:

macro julia_cmd(s)
    esc(Meta.quot(parse(s)))
end

Nous pouvons utiliser cette macro soit en ligne:

julia> julia`1+1`
:(1 + 1)

julia> julia`hypot2(x,y)=x^2+y^2`
:(hypot2(x,y) = begin  # none, line 1:
            x ^ 2 + y ^ 2
        end)

ou multiligne:

julia> julia```
       function hello()
           println("Hello, World!")
       end
       ```
:(function hello() # none, line 2:
        println("Hello, World!")
    end)

L'interpolation à l'aide de $ est prise en charge:

julia> x = 2
2

julia> julia`1 + $x`
:(1 + 2)

mais la version donnée ici ne permet qu'une seule expression:

julia> julia```
       x = 2
       y = 3
       ```
ERROR: ParseError("extra token after end of expression")

Cependant, l'étendre pour gérer plusieurs expressions n'est pas difficile.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow