Поиск…


Введение в выражения

Выражения - это особый тип объекта в Джулии. Вы можете представить выражение как часть кода Юлии, которая еще не была оценена (т.е. выполнена). Существуют конкретные функции и операции, такие как eval() которые будут оценивать выражение.

Например, мы могли бы написать скрипт или ввести в интерпретатор следующее: julia> 1 + 1 2

Один из способов создания выражения - использовать синтаксис :() . Например:

julia> MyExpression = :(1+1)
:(1 + 1)
julia> typeof(MyExpression)
Expr

Теперь у нас есть Expr типа Expr . Только что сформировавшись, он ничего не делает - он просто сидит, как любой другой объект, пока он не будет действовать. В этом случае мы можем оценить это выражение, используя функцию eval() :

julia> eval(MyExpression)
2

Таким образом, мы видим, что следующие два эквивалентны:

1+1
eval(:(1+1))

Почему мы хотим пройти гораздо более сложный синтаксис в eval(:(1+1)) если мы просто хотим найти то, что 1 + 1 равно? Основная причина заключается в том, что мы можем определить выражение в одной точке нашего кода, потенциально модифицировать его позже, а затем оценить его в более поздней точке. Это потенциально может открыть новые мощные возможности для программиста Julia. Выражения являются ключевым компонентом метапрограммирования в Джулии.

Создание выражений

Существует несколько различных методов, которые можно использовать для создания одного и того же типа выражения. В выражении intro упоминается синтаксис :() . Возможно, лучшее место для начала, однако, связано со строками. Это помогает выявить некоторые фундаментальные сходства между выражениями и строками в Джулии.

Создать выражение из строки

Из документации Julia:

Каждая программа Джулии начинает жизнь как строка

Другими словами, любой скрипт Джулии просто написан в текстовом файле, который представляет собой ни что иное, как строку символов. Аналогично, любая команда Julia, введенная в интерпретатор, представляет собой всего лишь строку символов. Роль Джулии или любого другого языка программирования заключается в том, чтобы интерпретировать и оценивать строки символов логичным, предсказуемым образом, чтобы эти строки символов могли использоваться для описания того, что программист хочет выполнить для компьютера.

Таким образом, одним из способов создания выражения является использование функции parse() применительно к строке. Следующее выражение, после его вычисления, присваивает значение 2 символу x .

MyStr = "x = 2"
MyExpr = parse(MyStr)
julia> x
ERROR: UndefVarError: x not defined
eval(MyExpr)
julia> x
2

Создать выражение с помощью :() Синтаксис

MyExpr2 = :(x = 2)
julia> MyExpr == MyExpr2
true

Обратите внимание, что с помощью этого синтаксиса Julia будет автоматически обрабатывать имена объектов как относящиеся к символам. Мы можем видеть это, если мы посмотрим на args выражения. (См. « Поля объектов выражения» для более подробной информации о поле args в выражении.)

julia> MyExpr2.args
2-element Array{Any,1}:
  :x
 2  

Создать выражение с помощью функции Expr()

MyExpr3 = Expr(:(=), :x, 2)
MyExpr3 == MyExpr

Этот синтаксис основан на нотации префикса . Другими словами, первый аргумент, указанный для функции Expr() является head или префиксом. Остальные arguments выражения. head определяет, какие операции будут выполняться по аргументам.

Дополнительные сведения об этом см. В разделе « Поля объектов выражения»

При использовании этого синтаксиса важно различать использование объектов и символов для объектов. Например, в приведенном выше примере выражение присваивает значению 2 символу :x - совершенно разумная операция. Если бы мы использовали сам x в таком выражении, мы получили бы бессмысленный результат:

julia> Expr(:(=), x, 5)
:(2 = 5)

Аналогично, если мы рассмотрим args мы видим:

julia> Expr(:(=), x, 5).args
2-element Array{Any,1}:
 2
 5

Таким образом, Expr() не выполняет одно и то же автоматическое преобразование в символы как синтаксис :() для создания выражений.

Создание многострочных выражений с использованием quote...end

MyQuote = 
quote
    x = 2
    y = 3
end
julia> typeof(MyQuote)
Expr

Обратите внимание, что с quote...end мы можем создавать выражения, содержащие другие выражения в поле args :

julia> typeof(MyQuote.args[2])
Expr

Дополнительные сведения об этом поле args см. В разделе « Поля объектов выражения» .

Подробнее о создании выражений

Этот пример просто дает основы для создания выражений. См. Также, например, Интерполяция и выражения и поля объектов выражения для получения дополнительной информации о создании более сложных и расширенных выражений.

Поля выражений

Как упоминалось в выражениях Intro to Expressions , это особый тип объекта в Julia. Таким образом, у них есть поля. Два наиболее используемых поля выражения - его head и его args . Например, рассмотрим выражение

MyExpr3 = Expr(:(=), :x, 2)

обсуждается в разделе «Создание выражений» . Мы можем видеть head и args следующим образом:

julia> MyExpr3.head
:(=)

julia> MyExpr3.args
2-element Array{Any,1}:
  :x
 2  

Выражения основаны на префиксной нотации . Таким образом, head обычно указывает операцию, которая должна выполняться на args . Голова должна быть Symbol типа Юлии.

Когда выражение должно назначать значение (когда оно оценивается), оно обычно использует заголовок :(=) . Конечно, существуют очевидные вариации, которые могут быть применены, например:

ex1 = Expr(:(+=), :x, 2)

: вызов для заголовков выражений

Еще одна общая head для выражений :call . Например

ex2 = Expr(:call, :(*), 2, 3)
eval(ex2) ## 6

Следуя соглашениям префиксной нотации, операторы оцениваются слева направо. Таким образом, это выражение означает, что мы будем называть функцию, указанную в первом элементе args для последующих элементов. Аналогичным образом мы могли бы:

julia> ex2a = Expr(:call, :(-), 1, 2, 3)
:(1 - 2 - 3)

Или другие, потенциально более интересные функции, например

julia> ex2b = Expr(:call, :rand, 2,2)
:(rand(2,2))

julia> eval(ex2b)
2x2 Array{Float64,2}:
 0.429397  0.164478
 0.104994  0.675745

Автоматическое определение head при использовании :() обозначения создания выражения

Обратите внимание, что :call неявно используется как глава в некоторых конструкциях выражений, например

julia> :(x + 2).head
:call

Таким образом, с синтаксисом :() для создания выражений, Julia будет стремиться автоматически определять правильную голову для использования. Так же:

julia> :(x = 2).head
:(=)

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

Интерполяция и выражения

Создание выражений означает, что выражения тесно связаны со строками. Таким образом, принципы интерполяции в строках также актуальны для выражений. Например, в базовой интерполяции строк мы можем иметь что-то вроде:

n = 2
julia> MyString = "there are $n ducks"
"there are 2 ducks"

Мы используем знак $ чтобы вставить значение n в строку. Мы можем использовать ту же технику с выражениями. Например

a = 2
ex1 = :(x = 2*$a)  ##     :(x = 2 * 2)
a = 3
eval(ex1)
x # 4

Сравните это с этим:

a = 2
ex2 = :(x = 2*a) # :(x = 2a)
a = 3
eval(ex2)
x # 6

Таким образом, в первом примере мы заранее устанавливаем значение a которое будет использоваться во время вычисления выражения. Однако со вторым примером компилятор Julia будет смотреть только на a чтобы найти его ценность во время оценки для нашего выражения.

Внешние ссылки на выражения

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

SO Сообщений:



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