Buscar..


Sintaxis

  • macro "cadena" # breve, forma de macro de cadena
  • @macro_str "cadena" # larga, forma de macro regular
  • macro`command`

Observaciones

Las macros de cadena no son tan poderosas como las cadenas simples, ya que la interpolación debe implementarse en la lógica de la macro, las macros de cadena no pueden contener literales de cadena del mismo delimitador para la interpolación.

Por ejemplo, aunque

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

funciona, la cadena de texto forma macro

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

se analiza incorrectamente. Esto se puede mitigar de alguna manera usando comillas triples como delimitador de cadena externo;

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

de hecho funciona correctamente.

Usando macros de cuerdas

Las macros de cadena son azúcar sintáctica para ciertas invocaciones de macro. El analizador expande la sintaxis como

mymacro"my string"

dentro

@mymacro_str "my string"

que luego, como cualquier otra llamada de macro, se sustituye por cualquier expresión que @mymacro_str macro @mymacro_str . Base Julia viene con varias macros de cuerdas, tales como:

@b_str

Esta macro de cadena construye matrices de bytes en lugar de cadenas . El contenido de la cadena, codificado como UTF-8, se utilizará como la matriz de bytes. Esto puede ser útil para interactuar con las API de bajo nivel, muchas de las cuales funcionan con matrices de bytes en lugar de cadenas.

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

@big_str

Esta macro devolverá un BigInt o un BigFloat analizado de la cadena que se proporciona.

julia> big"1"
1

julia> big"1.0"
1.000000000000000000000000000000000000000000000000000000000000000000000000000000

Esta macro existe porque big(0.1) no se comporta como se podría esperar inicialmente: 0.1 es una aproximación de Float64 de 0.1 ( 1//10 ), y promoverla a BigFloat mantendrá el error de aproximación de Float64 . El uso de la macro analizará 0.1 directamente a un BigFloat , reduciendo el error de aproximación.

julia> big(0.1)
1.000000000000000055511151231257827021181583404541015625000000000000000000000000e-01

julia> big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

@doc_str

Esta macro de cadena construye objetos Base.Markdown.MD , que se utilizan en el sistema de documentación interno para proporcionar documentación de texto enriquecido para cualquier entorno. Estos objetos MD se reproducen bien en un terminal:

La documentación de reducción de terminal se muestra bien.

y también en un navegador:

La documentación del markdown del navegador funciona bien.

@html_str

Esta macro de cadena construye literales de cadena HTML, que se reproducen bien en un navegador:

macro de cadena html que se representa muy bien en un navegador

@ip_str

Esta macro de cadena construye literales de dirección IP. Funciona tanto con IPv4 como con IPv6:

julia> ip"127.0.0.1"
ip"127.0.0.1"

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

@r_str

Esta macro de cadena construye Regex literales .

@s_str

Esta macro de cadena construye los literales SubstitutionString , que funcionan junto con los literales Regex para permitir una sustitución textual más avanzada.

@text_str

Esta macro de cadena es similar en espíritu a @doc_str y @html_str , pero no tiene ninguna característica de formato de fantasía:

texto plano en el navegador

@v_str

Esta macro de cadena construye los literales de VersionNumber . Consulte Números de versión para obtener una descripción de qué son y cómo usarlos.

@MIME_str

Esta macro de cadena construye los tipos singleton de tipos MIME. Por ejemplo, MIME"text/plain" es el tipo de MIME("text/plain") .

Símbolos que no son identificadores legales

Los literales de Julia Symbol deben ser identificadores legales. Esto funciona:

julia> :cat
:cat

Pero esto no lo hace:

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
  ...

Lo que parece un símbolo literal aquí en realidad se analiza como una multiplicación implícita de :2 (que es solo 2 ) y la función cat , que obviamente no funciona.

Nosotros podemos usar

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

para solucionar el problema.

Una macro de cadena podría ayudar a hacer esto más conciso. Si definimos la macro @sym_str :

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

entonces podemos simplemente hacer

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

Para crear símbolos que no sean identificadores de Julia válidos.

Por supuesto, estas técnicas también pueden crear símbolos que son identificadores de Julia válidos. Por ejemplo,

julia> sym"test"
:test

Implementando interpolación en una macro de cadena

Las macros de cadenas no vienen con instalaciones de interpolación incorporadas. Sin embargo, es posible implementar manualmente esta funcionalidad. Tenga en cuenta que no es posible incrustar sin escapar literales de cadena que tienen el mismo delimitador que la macro de cadena circundante; es decir, aunque """ $("x") """ es posible, " $("x") " no lo es. En su lugar, esto debe escaparse como " $(\"x\") " . Consulte la sección de comentarios para obtener más detalles sobre esta limitación.

Hay dos enfoques para implementar la interpolación manualmente: implementar el análisis manualmente, o hacer que Julia haga el análisis. El primer enfoque es más flexible, pero el segundo es más fácil.

Análisis manual

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 analizando

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

Este método escapa de la cadena (pero tenga en cuenta que escape_string no escapa de los signos $ ) y se lo pasa al analizador de Julia para analizarlo. El escape de la cadena es necesario para garantizar que " y \ no afecten el análisis de la cadena. La expresión resultante es una :string expresión de :string , que se puede examinar y descomponer para propósitos de macro.

Macros de comando

0.6.0-dev

En Julia v0.6 y versiones posteriores, las macros de comandos son compatibles además de las macros de cadena normales. Una invocación de macro de comando como

mymacro`xyz`

se analiza como la llamada macro

@mymacro_cmd "xyz"

Tenga en cuenta que esto es similar a las macros de cadenas, excepto con _cmd lugar de _str .

Utilizamos típicamente macros de comando de código, que en muchos idiomas con frecuencia contiene " pero rara vez contiene ` Por ejemplo, es bastante sencillo volver a implementar una versión simple de. Quasiquoting usando macros de comando:

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

Podemos usar esta macro ya sea en línea:

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)

o multilínea:

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

Se admite la interpolación usando $

julia> x = 2
2

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

pero la versión dada aquí solo permite una expresión:

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

Sin embargo, extenderlo para manejar múltiples expresiones no es difícil.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow