Поиск…


Синтаксис

  • макрос «строка» # короткая, строковая макроформа
  • @macro_str "string" # long, регулярная макроформа
  • macro`command`

замечания

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

Например, хотя

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

работает, текстовая форма строки

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

неправильно анализируется. Это можно несколько смягчить, используя тройные кавычки в качестве внешнего ограничителя строк;

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

действительно работает правильно.

Использование строковых макросов

Макросы строк - это синтаксический сахар для определенных макросов. Синтаксический анализатор расширяет синтаксис как

mymacro"my string"

в

@mymacro_str "my string"

который затем, как и любой другой макрокоманд, заменяется любым выражением, возвращаемым макросом @mymacro_str . База Julia поставляется с несколькими строковыми макросами, такими как:

@b_str

Этот строковый макрос строит байтовые массивы вместо строк . Содержимое строки, закодированной как UTF-8, будет использоваться как массив байтов. Это может быть полезно для взаимодействия с низкоуровневыми API-интерфейсами, многие из которых работают с байтовыми массивами вместо строк.

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

@big_str

Этот макрос вернет BigInt или BigFloat проанализированный из строки, которую он дал.

julia> big"1"
1

julia> big"1.0"
1.000000000000000000000000000000000000000000000000000000000000000000000000000000

Этот макрос существует, потому что big(0.1) не ведет себя так, как изначально ожидалось: 0.1 - это аппроксимация Float64 истины 0.1 ( 1//10 ), и продвижение этого BigFloat в BigFloat будет поддерживать ошибку аппроксимации Float64 . Использование макроса будет анализировать 0.1 непосредственно на BigFloat , уменьшая погрешность аппроксимации.

julia> big(0.1)
1.000000000000000055511151231257827021181583404541015625000000000000000000000000e-01

julia> big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

@doc_str

Этот строковый макрос Base.Markdown.MD объекты Base.Markdown.MD , которые используются во внутренней документации для предоставления полнотекстовой документации для любой среды. Эти объекты MD хорошо отображаются в терминале:

документация по терминальной маркировке

а также в браузере:

документация обозревателя браузера

@html_str

Этот строковый макрос создает строковые литералы HTML, которые хорошо отображаются в браузере:

html строка макрос рендеринга красиво в браузере

@ip_str

Этот строковый макрос создает литералы IP-адреса. Он работает как с IPv4, так и с IPv6:

julia> ip"127.0.0.1"
ip"127.0.0.1"

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

@r_str

Этот строковый макрос Regex литералы Regex .

@s_str

Этот строковый макрос SubstitutionString литералы SubstitutionString , которые работают вместе с литералами Regex чтобы обеспечить более продвинутую текстовую замену.

@text_str

Этот строковый макрос похож по духу на @doc_str и @html_str , но не имеет каких-либо причудливых особенностей форматирования:

простой текст в браузере

@v_str

Этот макрос строк VersionNumber литералы VersionNumber . См. Номера версий для описания того, что они есть и как их использовать.

@MIME_str

Этот строковый макрос создает однотипные типы MIME-типов. Например, MIME"text/plain" - это тип MIME("text/plain") .

Символы, которые не являются юридическими идентификаторами

Литералы Джулии Символы должны быть юридическими идентификаторами. Это работает:

julia> :cat
:cat

Но это не так:

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

То, что похоже на буквенный символ здесь, фактически анализируется как неявное умножение :2 (это всего лишь 2 ) и функция cat , которая, очевидно, не работает.

Мы можем использовать

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

для решения этой проблемы.

Строковый макрос может помочь сделать это более кратким. Если мы определяем макрос @sym_str :

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

то мы можем просто сделать

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

для создания символов, которые не являются действительными идентификаторами Юлии.

Конечно, эти методы также могут создавать символы, которые являются действительными идентификаторами Юлии. Например,

julia> sym"test"
:test

Реализация интерполяции в строковом макросе

Макросы String не оснащены встроенными средствами интерполяции . Тем не менее, это можно реализовать вручную. Обратите внимание, что невозможно вставлять без экранирования строковых литералов, которые имеют тот же разделитель, что и окружающий строковый макрос; то есть, хотя возможно """ $("x") """ , " $("x") " нет. Вместо этого это должно быть экранировано как " $(\"x\") " . Дополнительную информацию об этом ограничении см. В разделе примечаний .

Существует два подхода к внедрению интерполяции вручную: реализовать парсинг вручную или заставить Джулию выполнять синтаксический анализ. Первый подход более гибкий, но второй подход проще.

Ручной анализ

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

Анализ Юлии

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

Этот метод экранирует строку (но учтите , что escape_string не избежать $ знаков) и передает его обратно в синтаксический анализатор Джулии разобрать. Экранирование строки необходимо для обеспечения того, чтобы " и \ не влияли на синтаксический анализ строки. Полученное выражение представляет собой :string выражение, которое можно анализировать и разлагать для целей макроса.

Командные макросы

0.6.0-DEV

В Julia v0.6 и более поздних версиях макросы команд поддерживаются в дополнение к регулярным строковым макросам. Вызов макроса команды, например

mymacro`xyz`

анализируется как вызов макроса

@mymacro_cmd "xyz"

Обратите внимание, что это похоже на строковые макросы, за исключением _cmd вместо _str .

Обычно мы используем команду макросы для кода, который во многих языках часто содержит " , но редко содержит ` Например, это довольно просто переописать простой вариант. Quasiquoting с помощью команды макросов:

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

Мы можем использовать этот макрос либо inline:

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)

или многострочный:

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

Поддерживается интерполяция с использованием $ :

julia> x = 2
2

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

но приведенная здесь версия допускает только одно выражение:

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

Однако расширить его для обработки нескольких выражений не сложно.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow