Переменные
Переменная в Julia — это имя, связанное со значением (или привязанное к нему). Ее целесообразно применять, когда вы хотите сохранить значение (полученное, например, после математических вычислений) для последующего использования. Пример:
# Присваиваем значение 10 переменной x
julia> x = 10
10
# Выполняем вычисления со значением x
julia> x + 1
11
# Переприсваиваем значение x
julia> x = 1 + 1
2
# Вы можете присваивать значения других типов, например текстовые строки
julia> x = "Hello World!"
"Hello World!"
Julia предоставляет чрезвычайно гибкую систему именования переменных. Имена переменных зависят от регистра и не имеют семантического значения (то есть язык не будет рассматривать переменные по-разному на основании их имен).
julia> x = 1.0
1.0
julia> y = -3
-3
julia> Z = "My string"
"My string"
julia> customary_phrase = "Hello world!"
"Hello world!"
julia> UniversalDeclarationOfHumanRightsStart = "人人生而自由,在尊严和权利上一律平等。"
"人人生而自由,在尊严和权利上一律平等。"
Допускаются имена Unicode (в кодировке UTF-8).
julia> δ = 0.00001
1.0e-5
julia> 안녕하세요 = "Hello"
"Hello"
В REPL Julia и некоторых других средах редактирования Julia вы можете вводить многие математические символы Unicode, набирая имя символа LaTeX, предваренное обратным слешем, за которым следует символ табуляции. Например, можно ввести имя переменной δ
, набрав \delta
-tab, или даже α̂⁽²⁾
, набрав \alpha
-tab-\hat
- tab-\^(2)
-tab. (Если вы где-то нашли символ, например в чужом коде, и не знаете, как его ввести, обратитесь к справке по REPL: просто введите ?
, а затем вставьте символ.)
При необходимости в Julia можно даже переопределить встроенные константы и функции (хотя это не рекомендуется делать во избежание возможной путаницы).
julia> pi = 3
3
julia> pi
3
julia> sqrt = 4
4
Однако, если вы попытаетесь переопределить встроенную константу или функцию, которая уже используется, Julia выдаст ошибку.
julia> pi
π = 3.1415926535897...
julia> pi = 3
ERROR: cannot assign a value to imported variable MathConstants.pi from module Main
julia> sqrt(100)
10.0
julia> sqrt = 4
ERROR: cannot assign a value to imported variable Base.sqrt from module Main
Разрешенные имена переменных
Имена переменных должны начинаться с буквы (A — Z или a — z), подчеркивания или подмножества кодов символов Unicode больше 00A0, в частности категории символов Unicode Lu/Ll/Lt/Lm/Lo/Nl (буквы), Sc/So (валюта и другие символы). Кроме того, разрешены некоторые другие буквоподобные символы (например, подмножество математических символов Sm). Последующие символы могут также включать ! и цифры (0—9 и другие символы категорий Nd/No), а также другие коды символов Unicode: диакритические знаки и другие модифицирующие символы (категории Mn/Mc/Me/Sk), некоторые пунктуационные коннекторы (категория Pc), штрихи и другие символы.
Операторы типа +
также являются допустимыми идентификаторами, но анализируются особым образом. В некоторых контекстах операторы могут использоваться так же, как переменные. Например, (+)
применяется для функции сложения, а (+) = f
перепишет ее. Большинство инфиксных операторов Unicode (в категории Sm), такие как ⊕
, анализируются как инфиксные операторы и доступны для определяемых пользователем методов (например, const ⊗ = kron
можно использовать для определения ⊗
как инфиксного кронекерова произведения). Операторы также могут иметь суффикс с модифицирующими символами, штрихами, нижними или верхними индексами. Например, +̂ₐ″
анализируется как инфиксный оператор с тем же приоритетом, что и +
. Между оператором, заканчивающимся буквой нижнего или верхнего индекса, и последующим именем переменной требуется пробел. Например, если +ᵃ
является оператором, то +ᵃx
должен быть записан как +ᵃ x
, чтобы отличаться от + ᵃx
, где ᵃx
— имя переменной.
Особый класс имен переменных — тот, который содержит только символы подчеркивания. Этим именам можно присваивать только значения, которые сразу же удаляются, и поэтому их нельзя использовать для присваивания значений другим переменным (то есть применять как rvalues
) либо каким-либо образом использовать последнее присвоенное им значение.
julia> x, ___ = size([2 2; 1 1])
(2, 2)
julia> y = ___
ERROR: syntax: all-underscore identifier used as rvalue
julia> println(___)
ERROR: syntax: all-underscore identifier used as rvalue
Единственными явно запрещенными именами для переменных являются имена встроенных ключевых слов.
julia> else = false
ERROR: syntax: unexpected "else"
julia> try = "No"
ERROR: syntax: unexpected "="
Некоторые символы Unicode считаются эквивалентными в идентификаторах. Различные способы ввода комбинируемых символов Unicode (например, акценты) рассматриваются как эквивалентные (в частности, идентификаторы Julia являются NFC-нормализованными). Julia также содержит несколько нестандартных эквивалентов для символов, которые визуально похожи и легко вводятся с помощью некоторых методов ввода. Символы Unicode ɛ
(U+025B: латинская маленькая буква open e) и µ
(U+00B5: знак «микро») рассматриваются как эквивалент соответствующих греческих букв. Средняя точка ·
(U+00B7) и греческий интерпункт ·
(U+0387) рассматриваются как математический оператор «точка» ⋅
(U+22C5). Знак «минус» −
(U+2212) рассматривается как эквивалент знака «дефис-минус» -
(U+002D).
Выражения присваивания и сравнение присваивания с изменением
При присваивании variable = value
имя variable
«привязывается» к вычисленному значению value
в правой части, причем все присваивание рассматривается в Julia как выражение, равное значению value
в правой части. Это означает, что присваивания можно объединять в цепочки (присваивать одно и то же значение value
нескольким переменным в виде variable1 = variable2 = value
) либо использовать в других выражениях. По этой же причине их результаты отображаются в REPL как значения из правой части. (Обычно в REPL отображается значение вычисляемого выражения.) Например, в данном случае значение 4
выражения b = 2+2
используется в другой арифметической операции и присваивании:
julia> a = (b = 2+2) + 3
7
julia> a
7
julia> b
4
Зачастую путают понятия присваивания (то есть назначения нового «имени» значению) и изменения значения. Если выполнить a = 2
, а затем a = 3
, «имя» a
станет ссылаться на новое значение 3
. Число 2
не изменилось, поэтому 2+2
будет равно 4
, а не 6
! Это различие становится более очевидным при работе с изменяемыми типами, такими как массивы, содержимое которых можно изменять:
julia> a = [1,2,3] # массив из 3 целых чисел
3-element Vector{Int64}:
1
2
3
julia> b = a # b и a — это имена одного и того же массива!
3-element Vector{Int64}:
1
2
3
В данном случае строка b = a
не приводит к копированию массива a
. Имя b
просто привязывается к тому же массиву a
: и b
, и a
«указывают» на один массив [1,2,3]
в памяти. Напротив, присваивание a[i] = value
изменяет содержимое массива, так что по именам a
и b
будет доступен измененный массив:
julia> a[1] = 42 # изменяем первый элемент
42
julia> a = 3.14159 # a теперь является именем другого объекта
3.14159
julia> b # b ссылается на исходный объект массива, который был изменен
3-element Vector{Int64}:
42
2
3
Таким образом, a[i] = value
(псевдоним для setindex!
) изменяет существующий объект массива в памяти, доступный по имени a
или b
. Если впоследствии задать a = 3.14159
, массив не изменится, а вместо этого имя a
будет просто перепривязано к другому объекту; массив по-прежнему будет доступен по имени b
. Еще одна распространенная синтаксическая конструкция для изменения существующего объекта имеет вид a.field = value
(псевдоним для setproperty!
). С ее помощью можно изменить изменяемую структуру (mutable struct
).
При вызове функции в Julia вы как бы присваиваете значения аргументов новым именам переменных, соответствующим аргументам функции, как описывается в разделе Поведение при передаче аргументов. (Согласно соглашению имена функций, изменяющих один или несколько своих аргументов, заканчиваются символом !
.)
Стилистические соглашения
Хотя Julia накладывает малое количество ограничений на допустимые имена, рекомендуется соблюдать следующие стандарты.
-
Имена переменных указываются в нижнем регистре.
-
Разделение слов может быть обозначено подчеркиванием (
'_'
), но использовать символы подчеркивания не рекомендуется , в противном случае имя будет трудночитаемым. -
Имена типов (
Type
) и модулей (Module
) начинаются с прописной буквы, а для разделения слов используется верблюжий стиль, а не подчеркивание. -
Имена функций (
function
) и макросов (macro
) указываются в нижнем регистре без подчеркиваний. -
Имена функции, которые записывают в свои аргументы, оканчиваются на
!
. Иногда их называют изменяемыми или внутренними, поскольку они предназначены для внесения изменений в свои аргументы после вызова функции, а не просто возвращают значение.
Дополнительные сведения о стилистических соглашениях см. в руководстве по стилю.