Документация Engee

Основные объекты

Введение

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

Некоторые общие примечания.

  • Чтобы применять функции модуля, используйте import Module для импорта модуля и Module.fn(x) для использования функций.

  • В качестве альтернативы using Module импортирует все экспортируемые функции Module в текущее пространство имен.

  • Традиционно имена функций, заканчивающиеся восклицательным знаком (!), изменяют свои аргументы. Некоторые функции имеют как изменяемые (например, sort!), так и неизменяемые (sort) версии.

Поведение Base и стандартных библиотек является стабильным, как определено в SemVer, только если оно задокументировано, т. е. включено в документацию по Julia и не помечено как нестабильное. Дополнительные сведения см. на странице вопросов и ответов по API.

Общие сведения

# Base.exitFunction

exit(code=0)

Останавливает программу и возвращает код выхода. Код выхода по умолчанию равен нулю. Это означает, что выполнение программы завершилось успешно. Во время интерактивного сеанса функцию exit() можно вызвать сочетанием клавиш ^D.

# Base.atexitFunction

atexit(f)

Регистрирует функцию f() без аргументов или с одним аргументом, вызываемую при выходе из процесса. Перехватчики atexit() вызываются в порядке LIFO (последним поступил — первым обслужен) и выполняются перед финализаторами объектов.

Если f имеет метод, определенный для одного целочисленного аргумента, она будет вызвана как f(n::Int32), где n — это текущий код выхода, иначе она будет вызвана что и у f().

Совместимость: Julia 1.9

Для формы с одним аргументом требуется версия Julia не ниже 1.9.

Перехватчики выхода могут вызывать exit(n). В этом случае Julia завершает выполнение с кодом выхода n (вместо изначального кода выхода). Если функцию exit(n) вызывают несколько перехватчиков выхода, Julia завершает выполнение с кодом выхода, соответствующим последнему перехватчику выхода, который вызвал exit(n). (Так как перехватчики выхода вызываются в порядке LIFO, последним вызвавшим будет первый зарегистрированный перехватчик.)

Примечание. После вызова всех перехватчиков выхода больше нельзя зарегистрировать ни один перехватчик выхода, и любой вызов atexit(f) после завершения работы всех перехватчиков приведет к исключению. Такая ситуация может возникнуть при регистрации перехватчиков выхода из фоновых задач, которые все еще могут параллельно выполняться во время завершения работы.

# Base.isinteractiveFunction

isinteractive() -> Bool

Определяет, выполняется ли интерактивный сеанс Julia.

# Base.summarysizeFunction

Base.summarysize(obj; exclude=Union{...}, chargeall=Union{...}) -> Int

Вычисляет объем памяти в байтах, занимаемый всеми уникальными объектами, которые доступны из аргумента.

Именованные аргументы

  • exclude: типы объектов, исключаемые из обхода.

  • chargeall: типы объектов, для которых всегда учитывается размер всех полей, даже если они обычно исключаются.

См. также описание sizeof.

Примеры

julia> Base.summarysize(1.0)
8

julia> Base.summarysize(Ref(rand(100)))
848

julia> sizeof(Ref(rand(100)))
8

# Base.__precompile__Function

__precompile__(isprecompilable::Bool)

Определяет, можно ли предварительно скомпилировать файл, вызывающий эту функцию. Значение по умолчанию — true. Если предварительная компиляция модуля или файла небезопасна, следует вызвать __precompile__(false), чтобы при попытке предварительной компиляции в Julia возникала ошибка.

# Base.includeFunction

Base.include([mapexpr::Function,] m::Module, path::AbstractString)

Вычисляет содержимое входного файла исходного кода в глобальной области модуля m. У каждого модуля (кроме объявленных с ключевым словом baremodule) есть собственное определение функции include без аргумента m, которое вычисляет содержимое файла в этом модуле. Возвращает результат последнего вычисленного выражения во входном файле. Во время включения в качестве локального для задачи пути включения задается путь к каталогу, содержащему файл. При вложенных вызовах функции include поиск осуществляется относительно этого пути. Эта функция обычно применяется для загрузки исходного кода в интерактивном режиме или для объединения файлов в пакетах, которые разбиты на несколько файлов исходного кода.

С помощью необязательного первого аргумента mapexpr можно преобразовать включаемый код перед его вычислением: для каждого анализируемого выражения expr в path функция include фактически вычисляет mapexpr(expr). Если аргумент mapexpr не указан, по умолчанию он равен identity.

Совместимость: Julia 1.5

Для передачи аргумента mapexpr требуется версия Julia 1.5.

# Base.MainInclude.includeFunction

include([mapexpr::Function,] path::AbstractString)

Вычисляет содержимое входного файла исходного кода в глобальной области содержащего модуля. У каждого модуля (кроме объявленных с ключевым словом baremodule) есть собственное определение функции include, которое вычисляет содержимое файла в этом модуле. Возвращает результат последнего вычисленного выражения во входном файле. Во время включения в качестве локального для задачи пути включения задается путь к каталогу, содержащему файл. При вложенных вызовах функции include поиск осуществляется относительно этого пути. Эта функция обычно применяется для загрузки исходного кода в интерактивном режиме или для объединения файлов в пакетах, которые разбиты на несколько файлов исходного кода. Аргумент path нормализуется с помощью функции normpath, которая разрешает символы относительного пути, такие как .., и преобразовывает / в соответствующий разделитель пути.

С помощью необязательного первого аргумента mapexpr можно преобразовать включаемый код перед его вычислением: для каждого анализируемого выражения expr в path функция include фактически вычисляет mapexpr(expr). Если аргумент mapexpr не указан, по умолчанию он равен identity.

Для вычисления содержимого файла в другом модуле используйте Base.include.

Совместимость: Julia 1.5

Для передачи аргумента mapexpr требуется версия Julia 1.5.

# Base.include_stringFunction

include_string([mapexpr::Function,] m::Module, code::AbstractString, filename::AbstractString="string")

Действует так же, как include, но считывает код из указанной строки, а не из файла.

С помощью необязательного первого аргумента mapexpr можно преобразовать включаемый код перед его вычислением: для каждого анализируемого выражения expr в code функция include_string фактически вычисляет mapexpr(expr). Если аргумент mapexpr не указан, по умолчанию он равен identity.

Совместимость: Julia 1.5

Для передачи аргумента mapexpr требуется версия Julia 1.5.

# Base.include_dependencyFunction

include_dependency(path::AbstractString)

В модуле объявляет, что файл, каталог или символьная ссылка, указанные в аргументе path (в виде относительного или абсолютного), являются зависимостью для предварительной компиляции. Это означает, что модуль потребуется перекомпилировать, если изменится время модификации path.

Требуется только в том случае, если модуль зависит от пути, который не используется посредством include. Действует только при компиляции.

# __init__Keyword

__init__

Функция __init__() в модуле выполняется сразу после первой загрузки модуля во время выполнения. Она вызывается один раз, после выполнения всех остальных операторов в модуле. Поскольку она вызывается после полного импорта модуля, сначала будут выполнены функции __init__ подмодулей. Два типичных применения функции __init__ — это вызов функций инициализации среды выполнения внешних библиотек C и инициализация глобальных констант, которые предусматривают использование указателей, возвращаемых внешними библиотеками. Дополнительные сведения см. в разделе руководства, посвященном модулям.

Примеры

const foo_data_ptr = Ref{Ptr{Cvoid}}(0)
function __init__()
    ccall((:foo_init, :libfoo), Cvoid, ())
    foo_data_ptr[] = ccall((:foo_data, :libfoo), Ptr{Cvoid}, ())
    nothing
end

# Base.whichMethod

which(f, types)

Возвращает метод аргумента f (объект Method), который будет вызываться для аргументов типов types.

Если types — абстрактный тип, возвращается метод, который будет вызываться функцией invoke.

См. также описание функции parentmodule и макросов @which и @edit в модуле InteractiveUtils.

# Base.methodsFunction

methods(f, [types], [module])

Возвращает таблицу методов для f.

Если указан аргумент types, возвращает массив методов соответствующих типов. Если указан аргумент module, возвращает массив методов, определенных в этом модуле. Можно также указать список модулей в виде массива.

Совместимость: Julia 1.4

Для указания модуля требуется версия Julia не ниже 1.4.

См. также описание метода which и макроса @which.

# Base.@showMacro

@show exs...

Выводит одно или несколько выражений с результатами в stdout и возвращает последний результат.

См. также описание show, @info, println.

Примеры

julia> x = @show 1+2
1 + 2 = 3
3

julia> @show x^2 x/2;
x ^ 2 = 9
x / 2 = 1.5

# ansKeyword

ans

Переменная, ссылающаяся на последнее вычисленное значение, автоматически заданное в интерактивной командной строке.

# Base.active_projectFunction

active_project()

Возвращает путь к активному файлу Project.toml. См. также описание Base.set_active_project.

# Base.set_active_projectFunction

set_active_project(projfile::Union{AbstractString,Nothing})

Устанавливает файл, указанный в projfile, в качестве активного файла Project.toml. См. также описание Base.active_project.

Совместимость: Julia 1.8

Для этой функции требуется версия Julia не ниже 1.8.

Ключевые слова

Ниже приведен список зарезервированных ключевых слов в Julia. baremodule, begin, break, catch, const, continue, do, else, elseif, end, export, false, finally, for, function, global, if, import, let, local, macro, module, quote, return, struct, true, try, using, while. Эти ключевые слова запрещено использовать в качестве имен переменных.

Также зарезервированы следующие последовательности из двух слов: abstract type, mutable struct, primitive type. Однако можно создавать переменные с именами: abstract, mutable, primitive и type.

И, наконец: where анализируется как инфиксный оператор для записи определений параметрических методов и типов; in и isa анализируются как инфиксные операторы; а outer анализируется как ключевое слово, когда используется для изменения области видимости переменной в спецификации итерации цикла for. Однако допускается создание переменных с именами where, in, isa или outer.

# moduleKeyword

module

Ключевое слово module объявляет объект Module (модуль) — отдельную глобальную рабочую область переменных. Внутри модуля можно делать видимыми имена из других модулей (путем импорта) или делать имена из данного модуля общедоступными (путем экспорта). Модули позволяют создавать определения верхнего уровня, не беспокоясь о конфликте имен, когда ваш код используется вместе с чьим-то еще. Дополнительные сведения см. в разделе руководства, посвященном модулям.

Примеры

module Foo
import Base.show
export MyType, foo

struct MyType
    x
end

bar(x) = 2x
foo(a::MyType) = bar(a.x) + 1
show(io::IO, a::MyType) = print(io, "MyType $(a.x)")
end

# exportKeyword

export

Ключевое слово export в модулях сообщает Julia, какие функции должны быть доступны пользователю. Например: export foo делает имя foo доступным при загрузке модуля командой using. Подробные сведения см. в разделе руководства, посвященном модулям.

# importKeyword

import

import Foo загружает модуль или пакет Foo. Доступ к именам из импортированного модуля Foo осуществляется через точечную нотацию (например, Foo.foo для доступа к имени foo). Подробные сведения см. в разделе руководства, посвященном модулям.

# usingKeyword

using

using Foo загружает модуль или пакет Foo и делает его имена, экспортированные с помощью ключевого слова export, доступными для использования напрямую. К именам также можно обращаться через точечную нотацию (например, Foo.foo для доступа к имени foo) независимо от того, экспортированы ли они с помощью export. Подробные сведения см. в разделе руководства, посвященном модулям.

# baremoduleKeyword

baremodule

baremodule объявляет модуль, который не содержит команду using Base или локальных определений eval и include. Тем не менее модуль Core импортируется. Иными словами,

module Mod

...

end

эквивалентно

baremodule Mod

using Base

eval(x) = Core.eval(Mod, x)
include(p) = Base.include(Mod, p)

...

end

# functionKeyword

function

Функции определяются с помощью ключевого слова function:

function add(a, b)
    return a + b
end

Сокращенная запись:

add(a, b) = a + b

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

# macroKeyword

macro

Ключевое слово macro определяет метод для вставки сформированного кода в программу. Макрос сопоставляет последовательность выражений, переданных в качестве аргументов, с возвращаемым выражением. Результирующее выражение подставляется в программу в месте вызова макроса. Макросы позволяют выполнять сформированный код, не вызывая eval: сформированный код просто становится частью окружающей программы. Аргументами макроса могут быть выражения, литеральные значения и символы. Макросы можно определять с переменным количеством аргументов (varargs), но они не принимают именованные аргументы. В каждый макрос также неявно передаются аргумент __source__, содержащий номер строки и имя файла, откуда вызывается макрос, и аргумент __module__, содержащий модуль, в котором расширяется макрос.

Дополнительные сведения о написании макросов см. в разделе руководства, посвященном метапрограммированию.

Примеры

julia> macro sayhello(name)
           return :( println("Hello, ", $name, "!") )
       end
@sayhello (macro with 1 method)

julia> @sayhello "Charlie"
Hello, Charlie!

julia> macro saylots(x...)
           return :( println("Say: ", $(x...)) )
       end
@saylots (macro with 1 method)

julia> @saylots "hey " "there " "friend"
Say: hey there friend

# returnKeyword

return

Оператор return x вызывает досрочный выход из функции с передачей значения x вызывающему объекту. Ключевое слово return без значения эквивалентно return nothing (см. описание константы nothing).

function compare(a, b)
    a == b && return "equal to"
    a < b ? "less than" : "greater than"
end

Как правило, оператор return можно помещать в любом месте в теле функции, в том числе в глубоко вложенных циклах или условных операторах, но будьте осторожны с блоками do. Например:

function test1(xs)
    for x in xs
        iseven(x) && return 2x
    end
end

function test2(xs)
    map(xs) do x
        iseven(x) && return 2x
        x
    end
end

В первом примере оператор return завершает выполнение функции test1, как только встречается четное число, поэтому вызов test1([5,6,7]) возвращает 12.

Во втором примере можно было бы ожидать того же самого, но на самом деле оператор return в этом случае осуществляет выход из внутренней функции (внутри блока do) и возвращает значение функции map. Поэтому вызов test2([5,6,7]) возвращает [5,12,7].

При использовании в выражении верхнего уровня (то есть вне функции) оператор return вызывает досрочное завершение всего текущего выражения верхнего уровня.

# doKeyword

do

Создает анонимную функцию и передает ее в качестве первого аргумента в вызов функции. Например:

map(1:10) do x
    2x
end

эквивалентно map(x->2x, 1:10).

Можно использовать несколько аргументов следующим образом.

map(1:10, 11:20) do x, y
    x + y
end

# beginKeyword

begin

Ключевые слова begin...end обозначают блок кода.

begin
    println("Hello, ")
    println("World!")
end

В begin обычно нет необходимости, потому что такие ключевые слова, как function и let, подразумевают начало блока кода. См. также описание ;.

Ключевое слово begin также может использоваться при индексации. В этом случае оно означает первый индекс коллекции или измерения массива.

Примеры

julia> A = [1 2; 3 4]
2×2 Array{Int64,2}:
 1  2
 3  4

julia> A[begin, :]
2-element Array{Int64,1}:
 1
 2

# endKeyword

end

Ключевое слово end указывает на завершение блока выражений, например module, struct, mutable struct, begin, let, for и т. д.

Ключевое слово end также может использоваться при индексации. В этом случае оно означает последний индекс коллекции или измерения массива.

Примеры

julia> A = [1 2; 3 4]
2×2 Array{Int64, 2}:
 1  2
 3  4

julia> A[end, :]
2-element Array{Int64, 1}:
 3
 4

# letKeyword

let

Блоки let создают строгую область и дополнительно вводят новые локальные привязки.

Как и другие конструкции области, блоки let определяют блок кода, в котором будут доступны представленные локальные переменные. Кроме того, этот синтаксис имеет особое значение для присваиваний, разделенных запятыми, и имен переменных, которые по желанию могут находиться в той же строке, что и let:

let var1 = value1, var2, var3 = value3
    code
end

Переменные, представленные в этой строке, являются локальными для блока let, и присваивания вычисляются по порядку, причем каждая правая часть вычисляется в пределах области без учета имени в левой части. По этой причине выражение let x = x будет иметь смысл, так как две переменные x различны, причем левая часть локально затеняет x из внешней области. Это может быть даже полезным, поскольку новые локальные переменные создаются заново при каждом входе в локальные области, но это проявляется только в том случае, если переменные продолжают существовать за пределами своей области вследствие замыканий.

В отличие от них, блоки begin также группируют несколько выражений вместе, но не вводят область видимости и не имеют специального синтаксиса присваивания.

Примеры

В приведенной ниже функции есть единственный x, который трижды итеративно обновляется с помощью map. Все возвращаемые замыкания ссылаются на этот x в его конечном значении:

julia> function test_outer_x()
           x = 0
           map(1:3) do _
               x += 1
               return ()->x
           end
       end
test_outer_x (generic function with 1 method)

julia> [f() for f in test_outer_x()]
3-element Vector{Int64}:
 3
 3
 3

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

julia> function test_let_x()
           x = 0
           map(1:3) do _
               x += 1
               let x = x
                   return ()->x
               end
           end
       end
test_let_x (generic function with 1 method)

julia> [f() for f in test_let_x()]
3-element Vector{Int64}:
 1
 2
 3

Все конструкции области, которые вводят новые локальные переменные, ведут себя подобным образом при многократном запуске. Отличительной особенностью let является его способность лаконично объявлять новые локальные переменные (local), которые могут затенять внешние переменные с тем же именем. Например, прямое использование аргумента функции do аналогичным образом записывает три разные переменные:

julia> function test_do_x()
           map(1:3) do x
               return ()->x
           end
       end
test_do_x (generic function with 1 method)

julia> [f() for f in test_do_x()]
3-element Vector{Int64}:
 1
 2
 3

# ifKeyword

if/elseif/else

Конструкция if/elseif/else позволяет выполнять условные вычисления: части кода вычисляются или не вычисляются в зависимости от значения логического выражения. Синтаксис условной конструкции if/elseif/else устроен следующим образом.

if x < y
    println("x is less than y")
elseif x > y
    println("x is greater than y")
else
    println("x is equal to y")
end

Если выражение условия x < y имеет значение true, то соответствующий блок вычисляется; в противном случае вычисляется выражение условия x > y, и если оно равно true, вычисляется соответствующий блок. Если ни одно из выражений не равно true, вычисляется блок else . Блоки elseif и else являются необязательными. Блоков elseif может быть сколько угодно.

В отличие от некоторых других языков, условия должны иметь тип Bool. Возможности преобразования условия в Bool недостаточно.

julia> if 1 end
ERROR: TypeError: non-boolean (Int64) used in boolean context

# forKeyword

for

Цикл for позволяет повторно вычислять блок операторов с итерацией по последовательности значений.

Переменная итерации — это всегда новая переменная, даже если переменная с таким именем уже существует во внешней области. Используйте outer для повторного применения существующей локальной переменной для итерации.

Примеры

julia> for i in [1, 4, 0]
           println(i)
       end
1
4
0

# whileKeyword

while

Цикл while позволяет повторно вычислять условное выражение и продолжать вычислять тело цикла while до тех пор, пока выражение равно true. Если условное выражение равно false при первом вычислении, тело цикла while никогда не вычисляется.

Примеры

julia> i = 1
1

julia> while i < 5
           println(i)
           global i += 1
       end
1
2
3
4

# breakKeyword

break

Осуществляет немедленный выход из цикла.

Примеры

julia> i = 0
0

julia> while true
           global i += 1
           i > 5 && break
           println(i)
       end
1
2
3
4
5

# continueKeyword

continue

Пропускает оставшуюся часть текущей итерации цикла.

Примеры

julia> for i = 1:6
           iseven(i) && continue
           println(i)
       end
1
3
5

# tryKeyword

try/catch

Оператор try/catch позволяет перехватывать ошибки (исключения), вызываемые функцией throw, чтобы выполнение программы могло продолжаться. Например, в следующем коде производится попытка записи в файл, но пользователь получает предупреждение и выполнение продолжается, если запись в файл невозможна:

try
    open("/danger", "w") do f
        println(f, "Hello")
    end
catch
    @warn "Could not write file."
end

или если файл невозможно считать в переменную:

lines = try
    open("/danger", "r") do f
        readlines(f)
    end
catch
    @warn "File not found."
end

С помощью синтаксиса catch e (где e — любая переменная) объект вызванного исключения присваивается указанной переменной в блоке catch.

Конструкция try/catch полезна тем, что позволяет сразу передать глубоко вложенное вычисление на гораздо более высокий уровень в стеке вызывающих функций.

# finallyKeyword

finally

Выполняет определенный код при выходе из заданного блока кода независимо от того, как происходит выход. Например, так можно гарантировать закрытие открытого файла:

f = open("file")
try
    operate_on_file(f)
finally
    close(f)
end

Когда управление передается из блока try (например, вследствие выполнения оператора return или из-за обычного завершения), выполняется функция close(f). Если выход из блока try произойдет вследствие исключения, это исключение будет передано далее. Блок catch также можно использовать в сочетании с try и finally. В этом случае блок finally будет выполнен после того, как блок catch обработает ошибку.

# quoteKeyword

quote

Ключевое слово quote создает несколько объектов выражений на основе блока кода без явного использования конструктора Expr. Например:

ex = quote
    x = 1
    y = 2
    x + y
end

В отличие от другого способа цитирования, :( ... ), этот способ добавляет в дерево выражений элементы QuoteNode, которые должны обрабатываться при операциях с деревом. Во всех остальных случаях блоки :( ... ) и quote .. end равноценны.

# localKeyword

local

Ключевое слово local объявляет новую локальную переменную. Дополнительные сведения см. в разделе руководства, посвященном областям переменных.

Примеры

julia> function foo(n)
           x = 0
           for i = 1:n
               local x # объявить локальную для цикла переменную x
               x = i
           end
           x
       end
foo (generic function with 1 method)

julia> foo(10)
0

# globalKeyword

global

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

Примеры

julia> z = 3
3

julia> function foo()
           global z = 6 # использовать переменную z, определенную вне foo
       end
foo (generic function with 1 method)

julia> foo()
6

julia> z
6

# outerKeyword

for outer

Повторно использует существующую локальную переменную для итерации в цикле for.

См. также описание for.

Примеры

julia> function f()
           i = 0
           for i = 1:3
               # пусто
           end
           return i
       end;

julia> f()
0
julia> function f()
           i = 0
           for outer i = 1:3
               # пусто
           end
           return i
       end;

julia> f()
3
julia> i = 0 # глобальная переменная
       for outer i = 1:3
       end
ERROR: syntax: no outer local variable declaration exists for "for outer"
[...]

# constKeyword

const

Ключевое слово const служит для объявления глобальных переменных, значения которых меняться не будут. Практически всегда (и особенно в коде, требовательном к производительности) глобальные переменные должны объявляться константами таким способом.

const x = 5

В одном выражении const можно объявить несколько переменных:

const y, z = 7, 11

Обратите внимание, что const применяется только к одной операции =, поэтому выражение const x = y = 1 объявляет константой только переменную x, но не y. В свою очередь, выражение const x = const y = 1 объявляет константами как x, так и y.

Обратите внимание на то, что «константность» не распространяется на изменяемые контейнеры; неизменяемой является только связь между переменной и ее значением. Например, если x — это массив или словарь, его элементы можно по-прежнему изменять, добавлять или удалять.

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

# structKeyword

struct

Самый широко применяемый тип в Julia — структура. Ее определение состоит из имени и набора полей.

struct Point
    x
    y
end

Поля могут иметь ограничения типов, которые могут быть параметризованы:

struct Point{X}
    x::X
    y::Float64
end

В структуре также может быть объявлен абстрактный супертип с помощью синтаксиса <::

struct Point <: AbstractPoint
    x
    y
end

По умолчанию экземпляры struct являются неизменяемыми: их нельзя изменить после создания. Однако с помощью ключевого слова mutable struct можно объявить тип, экземпляры которого допускают изменение.

В разделе руководства, посвященном составным типам, приводятся дополнительные сведения, например об определении конструкторов.

# mutable structKeyword

mutable struct

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

# Base.@kwdefMacro

@kwdef typedef

Это вспомогательный макрос, который автоматически определяет конструктор на основе ключевого слова для типа, объявленного в выражении typedef, которое должно быть выражением struct или mutable struct Julia. Аргумент по умолчанию указывается при объявлении полей видаfield::T = defaultorfield = default. Если значение по умолчанию не указано, именованный аргумент становится обязательным именованным аргументом в конструкторе результирующего типа.

Внутренние конструкторы по-прежнему могут быть определены, но по крайней мере один из них должен принимать аргументы в том же виде, что и внутренний конструктор по умолчанию (т. е. один позиционный аргумент на поле), чтобы корректно работать с внешним конструктором ключевых слов.

Совместимость: Julia 1.1

Для Base.@kwdef для параметрических структур и структур с супертипами требуется версия Julia не ниже 1.1.

Совместимость: Julia 1.9

Этот макрос экспортируется начиная с версии Julia 1.9.

Примеры

julia> @kwdef struct Foo
           a::Int = 1         # указанное значение по умолчанию
           b::String          # требуемое ключевое слово
       end
Foo

julia> Foo(b="hi")
Foo(1, "hi")

julia> Foo()
ERROR: UndefKeywordError: keyword argument `b` not assigned
Stacktrace:
[...]

# abstract typeKeyword

abstract type

abstract type объявляет тип, который не допускает создания экземпляров, а просто служит узлом в графе типов, описывая наборы связанных конкретных типов — типов, являющихся потомками данного абстрактного типа. Абстрактные типы образуют концептуальную иерархию, благодаря которой система типов Julia представляет собой нечто большее, чем просто коллекцию реализаций объектов. Например:

abstract type Number end
abstract type Real <: Number end

У Number нет супертипа, в то время как Real является абстрактным подтипом типа Number.

# primitive typeKeyword

primitive type

primitive type объявляет конкретный тип, данные которого состоят только из последовательности битов. Классическими примерами примитивных типов являются целые числа и значения с плавающей запятой. Вот некоторые примеры встроенных объявлений примитивных типов.

primitive type Char 32 end
primitive type Bool <: Integer 8 end

Число после имени означает то, сколько битов требуется для хранения типа. В настоящее время поддерживаются только размеры, кратные 8 битам. Объявление Bool демонстрирует, как примитивный тип можно объявить как подтип какого-либо супертипа.

# whereKeyword

where

Ключевое слово where создает тип, который является итерируемым объединением других типов по всем значениям некоторой переменной. Например, тип Vector{T} where T<:Real включает в себя все векторы (Vector), элементы которых являются вещественными числами (Real).

Если ограничивающая переменная не указана, по умолчанию она равна Any:

Vector{T} where T    # краткая форма для `where T<:Any`

Переменные также могут иметь нижние границы:

Vector{T} where T>:Int
Vector{T} where Int<:T<:Real

Существует также сокращенный синтаксис для вложенных выражений where. Например, такой код:

Pair{T, S} where S<:Array{T} where T<:Number

можно сократить следующим образом:

Pair{T, S} where {T<:Number, S<:Array{T}}

Такая форма часто встречается в сигнатурах методов.

Обратите внимание, что при использовании такой формы записи переменные перечисляются начиная с самой внешней. Это соответствует порядку, в котором переменные подставляются при применении типа к значениям параметров с помощью синтаксиса T{p1, p2, ...}.

# ...Keyword

...

Оператор расширения (splat-оператор, ...) представляет последовательность аргументов. Оператор ... можно использовать в определениях функций для указания на то, что функция принимает произвольное количество аргументов. С помощью оператора ... можно также применять функцию к последовательности аргументов.

Примеры

julia> add(xs...) = reduce(+, xs)
add (generic function with 1 method)

julia> add(1, 2, 3, 4, 5)
15

julia> add([1, 2, 3]...)
6

julia> add(7, 1:100..., 1000:1100...)
111107

# ;Keyword

;

Символ ; выполняет в Julia ту же роль, что и во многих С-подобных языках, обозначая конец предыдущего оператора.

Символ ; необязательно должен стоять в конце строки: он может использоваться для отделения операторов в одной строке или для объединения операторов в одно выражение.

Если добавить ; в конец строки в REPL, результат этого выражения не выводится.

В объявлениях функций символ ; отделяет обычные аргументы от именованных. С этой же целью его можно применять в вызовах функций.

Если при создании массива аргументы в квадратных скобках разделяются символом ;, их содержимое объединяется по вертикали.

Если в стандартной среде REPL ввести символ ; в пустой строке, она переключится в режим оболочки.

Примеры

julia> function foo()
           x = "Hello, "; x *= "World!"
           return x
       end
foo (generic function with 1 method)

julia> bar() = (x = "Hello, Mars!"; return x)
bar (generic function with 1 method)

julia> foo();

julia> bar()
"Hello, Mars!"

julia> function plot(x, y; style="solid", width=1, color="black")
           ###
       end

julia> [1 2; 3 4]
2×2 Matrix{Int64}:
 1  2
 3  4

julia> ; # при вводе ;, приглашение к вводу меняется на shell>
shell> echo hello
hello

# =Keyword

=

= — это оператор присваивания.

  • Если a — переменная, а b — выражение, в результате присваивания a = b переменная a будет ссылаться на значение b.

  • Для функции f(x) присваивание f(x) = x определяет новую функцию-константу f или, если функция f уже определена, добавляет в f новый метод. Такой вариант использования эквивалентен синтаксису function f(x); x; end.

  • a[i] = v вызывает xref:./collections.adoc#Base.setindex!(a,v,i).

  • a.b = c вызывает xref:./base.adoc#Base.setproperty!(a,:b,c).

  • Внутри вызова функции f(a=b) передает b в качестве значения именованного аргумента a.

  • Внутри скобок с запятыми (a=1,) создает экземпляр типа NamedTuple.

Примеры

При присваивании объекта b переменной a копия b не создается; для этого нужно использовать функцию copy или deepcopy.

julia> b = [1]; a = b; b[1] = 2; a
1-element Array{Int64, 1}:
 2

julia> b = [1]; a = copy(b); b[1] = 2; a
1-element Array{Int64, 1}:
 1

Коллекции, передаваемые в функции, также не копируются. Функции могут изменять содержимое объектов, на которые ссылаются их аргументы. (К именам таких функций принято добавлять суффикс «!».)

julia> function f!(x); x[:] .+= 1; end
f! (generic function with 1 method)

julia> a = [1]; f!(a); a
1-element Array{Int64, 1}:
 2

Значения итерируемого объекта можно присваивать параллельно нескольким переменным:

julia> a, b = 4, 5
(4, 5)

julia> a, b = 1:3
1:3

julia> a, b
(1, 2)

Присваивать значения можно последовательно нескольким переменным. При этом возвращается значение самого правого выражения:

julia> a = [1]; b = [2]; c = [3]; a = b = c
1-element Array{Int64, 1}:
 3

julia> b[1] = 2; a, b, c
([2], [2], [2])

При присваивании по индексу, выходящему за границы, элементы в коллекцию не добавляются. Если коллекция имеет тип Vector, добавить в нее элементы можно с помощью функции push! или append!.

julia> a = [1, 1]; a[3] = 2
ERROR: BoundsError: attempt to access 2-element Array{Int64, 1} at index [3]
[...]

julia> push!(a, 2, 3)
4-element Array{Int64, 1}:
 1
 1
 2
 3

При присваивании [] элементы из коллекции не удаляются; вместо этого используйте функцию filter!.

julia> a = collect(1:3); a[a .<= 1] = []
ERROR: DimensionMismatch: tried to assign 0 elements to 1 destinations
[...]

julia> filter!(x -> x > 1, a) # операция производится на месте и поэтому эффективнее, чем a = a[a .> 1]
2-element Array{Int64, 1}:
 2
 3

# ?:Keyword

a ? b : c

Краткая форма записи условных операторов; означает «если a, вычислить b, в противном случае вычислить c». Также называется тернарным оператором.

Этот синтаксис эквивалентен if a; b else c end, но часто применяется, чтобы подчеркнуть выбор между b и c в рамках более сложного выражения, а не последствия вычисления b или c.

Дополнительные сведения см. в разделе руководства, посвященном порядку выполнения.

Примеры

julia> x = 1; y = 2;

julia> x > y ? println("x is larger") : println("y is larger")
y is larger

Стандартные модули

# MainModule

Main

Main — это модуль верхнего уровня. Изначально в Julia модуль Main является текущим. Переменные, определяемые в командной строке, добавляются в модуль Main, а функция varinfo возвращает переменные из модуля Main.

julia> @__MODULE__
Main

# CoreModule

Core

В модуле Core содержатся все идентификаторы, которые считаются встроенными в язык, то есть являются частью самого языка, а не библиотек. В каждом модуле неявно применяется команда using Core, так как без этих определений никакие операции невозможны.

# BaseModule

Base

Базовая библиотека Julia. В модуле Base содержатся основные функции (содержимое base/). Во всех модулях неявно применяется команда using Base, так как эти функции необходимы в подавляющем большинстве случаев.

Подмодули Base

# Base.BroadcastModule

Base.Broadcast

Модуль, содержащий реализацию трансляции.

# Base.DocsModule

Docs

Модуль Docs предоставляет макрос @doc, с помощью которого можно задавать и получать метаданные документации для объектов Julia.

Дополнительные сведения см. в разделе руководства, посвященном документации .

# Base.IteratorsModule

Методы для работы с итераторами.

# Base.LibcModule

Интерфейс для libc, стандартной библиотеки С.

# Base.MetaModule

Вспомогательные функции для метапрограммирования.

# Base.StackTracesModule

Инструменты для сбора трассировок стека и работы с ними. В основном используются для устранения ошибок сборки.

# Base.SysModule

Предоставляет методы получения информации об аппаратном обеспечении и операционной системе.

# Base.ThreadsModule

Поддержка многопоточности.

# Base.GCModule

Base.GC

Модуль со средствами сборки мусора.

Все объекты

# Core.:===Function

===(x,y) -> Bool
≡(x,y) -> Bool

Определяет, являются ли x и y идентичными, то есть неотличимыми для любой программы. Сначала сравниваются типы x и y. Если они одинаковы, изменяемые объекты сравниваются по адресу в памяти, а неизменяемые (например, числа) — по содержимому на уровне битов. Иногда эту функцию называют egal. Она всегда возвращает значение типа Bool.

Примеры

julia> a = [1, 2]; b = [1, 2];

julia> a == b
true

julia> a === b
false

julia> a === a
true

# Core.isaFunction

isa(x, type) -> Bool

Определяет, относится ли x к типу type. Также может применяться как инфиксный оператор, например x isa type.

Примеры

julia> isa(1, Int)
true

julia> isa(1, Matrix)
false

julia> isa(1, Char)
false

julia> isa(1, Number)
true

julia> 1 isa Number
true

# Base.isequalFunction

isequal(x, y)

Аналогично ==, за исключением обработки чисел с плавающей запятой и отсутствующих значений. Функция isequal расценивает все значения NaN с плавающей запятой как равные друг другу, значение -0.0 — как неравное 0.0, а значение missing — как равное в файл missing. Всегда возвращает значение типа Bool.

isequal — это отношение эквивалентности: оно рефлексивное (=== влечет isequal), симметричное (isequal(a, b) влечет isequal(b, a)) и транзитивное (isequal(a, b) и isequal(b, c) влечет isequal(a, c)).

Реализация

Реализация функции isequal по умолчанию вызывает ==, поэтому для типа, не связанного со значениями с плавающей запятой, как правило, достаточно использовать ==.

isequal — это функция сравнения, используемая хэш-таблицами (Dict). Из isequal(x,y) должно вытекать, что hash(x) == hash(y).

Обычно это означает, что типы, для которых существует пользовательский метод == или isequal, должны реализовывать соответствующий метод hash (и наоборот). Реализация isequal для коллекций обычно вызывает isequal рекурсивно для всего содержимого.

Кроме того, функция isequal связана с isless, и вместе они определяют фиксированный общий порядок: только одно из выражений isequal(x, y), isless(x, y) или isless(y, x) должно быть равно true (а остальные два — false).

Скалярные типы обычно не требуют реализации isequal отдельно от ==, если только они не представляют числа с плавающей запятой, для которых возможна более эффективная реализация, чем универсальный метод (на основе isnan, signbit и ==).

Примеры

julia> isequal([1., NaN], [1., NaN])
true

julia> [1., NaN] == [1., NaN]
false

julia> 0.0 == -0.0
true

julia> isequal(0.0, -0.0)
false

julia> missing == missing
missing

julia> isequal(missing, missing)
true
isequal(x)

Создает функцию, аргумент которой сравнивается с x через isequal, т. е. функцию, эквивалентную y -> isequal(y, x).

Возвращаемая функция имеет тип Base.Fix2{typeof(isequal)} и может использоваться для реализации специализированных методов.

# Base.islessFunction

isless(x, y)

Проверяет, меньше ли x, чем y, в соответствии с фиксированным общим порядком (определяется в сочетании с функцией isequal). Функция isless определена не для всех пар значений (x, y). Однако если она определена, должны выполняться следующие условия.

  • Если определено isless(x, y), то также должно быть определено isless(y, x) и isequal(x, y) и только одно из этих трех выражений должно возвращать значение true.

  • Отношение, определяемое функцией isless, является транзитивным, то есть Утверждение isless(x, y) && isless(y, z) подразумевает isless(x, z).

Значения, которые обычно являются неупорядоченными, например NaN, следуют за обычными значениями. В порядке следования значений missing находится в самом конце.

Это сравнение по умолчанию, используемое функцией sort.

Реализация

Эта функция должна быть реализована для нечисловых типов, имеющих общий порядок. Для числовых типов ее необходимо реализовывать, только если тип предусматривает особые значения, например NaN. Типы с частичным порядком должны реализовывать <. В документации по альтернативным порядкам можно узнать, как определяются альтернативные методы упорядочивания, которые используются при сортировке и в тому подобных функциях.

Примеры

julia> isless(1, 3)
true

julia> isless("Red", "Blue")
false

# Base.ifelseFunction

ifelse(condition::Bool, x, y)

Возвращает x, если condition равно true, в противном случае возвращает y. Отличается от ? или if тем, что это обычная функция, поэтому сначала вычисляются все аргументы. В некоторых случаях использование ifelse вместо оператора if позволяет устранить ветвление в сформированном коде и обеспечить более высокую производительность сплошных циклов.

Примеры

julia> ifelse(1 > 2, 1, 2)
2

# Core.typeassertFunction

typeassert(x, type)

Вызывает ошибку TypeError, если не выполняется условие x isa type. Эта функция вызывается при использовании синтаксиса x::type.

Примеры

julia> typeassert(2.5, Int)
ERROR: TypeError: in typeassert, expected Int64, got a value of type Float64
Stacktrace:
[...]

# Core.typeofFunction

typeof(x)

Возвращает конкретный тип аргумента x.

См. также описание eltype.

Примеры

julia> a = 1//2;

julia> typeof(a)
Rational{Int64}

julia> M = [1 2; 3.5 4];

julia> typeof(M)
Matrix{Float64} (alias for Array{Float64, 2})

# Core.tupleFunction

tuple(xs...)

Создает кортеж из указанных объектов.

См. также описание Tuple и NamedTuple.

Примеры

julia> tuple(1, 'b', pi)
(1, 'b', π)

julia> ans === (1, 'b', π)
true

julia> Tuple(Real[1, 2, pi])  # принимает коллекцию
(1, 2, π)

# Base.ntupleFunction

ntuple(f::Function, n::Integer)

Создает кортеж длины n, каждый элемент которого вычисляется с помощью функции f(i), где i — индекс элемента.

Примеры

julia> ntuple(i -> 2*i, 4)
(2, 4, 6, 8)
ntuple(f, ::Val{N})

Создает кортеж длины N, каждый элемент которого вычисляется с помощью функции f(i), где i — индекс элемента. Благодаря аргументу Val(N) код, создаваемый с помощью этого варианта функции ntuple, может быть эффективнее, чем при указании длины в виде целого числа. Но вариант ntuple(f, N) предпочтительнее ntuple(f, Val(N)) в случаях, когда N невозможно определить во время компиляции.

Примеры

julia> ntuple(i -> 2*i, Val(4))
(2, 4, 6, 8)

# Base.objectidFunction

objectid(x) -> UInt

Возвращает хэш-значение для x на основе идентификатора объекта.

Если x === y, то objectid(x) == objectid(y), и обычно когда x !== y, objectid(x) != objectid(y).

См. также описание hash и IdDict.

# Base.hashFunction

hash(x[, h::UInt]) -> UInt

Вычисляет такой целочисленный хэш-код, что из isequal(x,y) следует hash(x)==hash(y).Необязательный второй аргумент h — это хэш-код, смешиваемый с результатом.

Для новых типов должна реализовываться форма с двумя аргументами. Для этого обычно функция hash с двумя аргументами вызывается рекурсивно с целью смешивания хэшей содержимого друг с другом (и с h). Как правило, любой тип, для которого реализована функция hash, должен также иметь собственную реализацию == (а следовательно, и isequal), чтобы выполнялось указанное выше условие. Типы, поддерживающие вычитание (оператор -), также должны реализовывать функцию widen, которая нужна для хэширования значений в неоднородных массивах.

julia> a = hash(10)
0x95ea2955abd45275

julia> hash(10, a) # использовать в качестве второго аргумента только выходные данные другой хэш-функции
0xd42bad54a8575b16

См. также описание objectid, Dict, Set.

# Base.finalizerFunction

finalizer(f, x)

Регистрирует функцию f(x), которая должна вызываться при отсутствии доступных программе ссылок на x и возвращается x. x должен иметь тип mutable struct, иначе эта функция выдаст ошибку.

Функция f не должна вызывать переключение задач, а значит, исключается большинство операций ввода-вывода, таких как println. В целях отладки может быть полезно использовать макрос @async (чтобы отложить переключение контекста до завершения выполнения финализатора) или ключевое слово ccall для вызова функций ввода-вывода на языке C напрямую.

Обратите внимание, что для выполнения функции f не гарантируется наличие «возраста мира». Ее можно вызывать в том «возрасте мира», в котором был зарегистрирован финализатор, или в любом более позднем «возрасте мира».

Примеры

finalizer(my_mutable_struct) do x
    @async println("Finalizing $x.")
end

finalizer(my_mutable_struct) do x
    ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.", repr(x))
end

Финализатор может быть зарегистрирован при создании объекта. Обратите внимание: в следующем примере неявно предполагается, что финализатор возвращает созданную изменяемую структуру x.

Пример

mutable struct MyMutableStruct
    bar
    function MyMutableStruct(bar)
        x = new(bar)
        f(t) = @async println("Finalizing $t.")
        finalizer(f, x)
    end
end

# Base.finalizeFunction

finalize(x)

Немедленно выполняет финализаторы, зарегистрированные для объекта x.

# Base.copyFunction

copy(x)

Создает поверхностную копию x: копируется внешняя структура, но не внутренние значения. Например, при копировании массива создается массив с теми же элементами, что и у исходного.

См. также описание функций copy!, copyto! и deepcopy.

# Base.deepcopyFunction

deepcopy(x)

Создает глубокую копию x: рекурсивно копируется все содержимое, так что получается полностью независимый объект. Например, при глубоком копировании массива создается массив, элементы которого являются глубокими копиями исходных элементов. Вызов функции deepcopy для объекта обычно равносилен его сериализации и последующей десериализации.

Хотя обычно это не требуется, в определяемых пользователем типах можно переопределить поведение функции deepcopy по умолчанию. Для этого определяется специализированная версия функции deepcopy_internal(x::T, dict::IdDict) (которая в иных целях не используется). Здесь T — это тип, для которого переопределяется функция, а dict отслеживает объекты, копируемые рекурсивно. В определении deepcopy_internal следует использовать вместо deepcopy, а переменную dict следует обновить соответствующим образом перед возвратом.

# Base.getpropertyFunction

getproperty(value, name::Symbol)
getproperty(value, name::Symbol, order::Symbol)

Синтаксис a.b вызывает getproperty(a, :b). С помощью синтаксиса @atomic order a.b делается вызов getproperty(a, :b, :order), а с помощью синтаксиса @atomic a.b — вызов getproperty(a, :b, :sequentially_consistent).

Примеры

julia> struct MyType
           x
       end

julia> function Base.getproperty(obj::MyType, sym::Symbol)
           if sym === :special
               return obj.x + 1
           else # использовать getfield
               return getfield(obj, sym)
           end
       end

julia> obj = MyType(1);

julia> obj.special
2

julia> obj.x
1

См. также описание функций getfield, propertynames и setproperty!.

# Base.setproperty!Function

setproperty!(value, name::Symbol, x)
setproperty!(value, name::Symbol, x, order::Symbol)

Синтаксис a.b = c вызывает setproperty!(a, :b, c). С помощью синтаксиса @atomic order a.b = c делается вызов setproperty!(a, :b, c, :order), а с помощью синтаксиса @atomic a.b = c — вызов setproperty!(a, :b, c, :sequentially_consistent).

Совместимость: Julia 1.8

Для setproperty! в модулях требуется версия Julia не ниже 1.8.

См. также описание функций setfield!, propertynames и getproperty.

# Base.propertynamesFunction

propertynames(x, private=false)

Возвращает кортеж или вектор свойств (x.property) объекта x. Обычно действует так же, как fieldnames(typeof(x)), но типы, которые перегружают функцию getproperty, как правило, должны также перегружать propertynames для получения свойств экземпляра типа.

Функция propertynames(x) может возвращать имена только общедоступных свойств, входящих в задокументированный интерфейс объекта x. Если нужно также вернуть имена частных свойств, предназначенных для внутреннего использования, передайте значение true для необязательного второго аргумента. При автозавершении клавишей TAB в REPL для x. отображаются только свойства, для которых private=false.

См. также описание hasproperty, hasfield.

# Base.haspropertyFunction

hasproperty(x, s::Symbol)

Возвращает логическое значение, указывающее, является ли s одним из собственных свойств объекта x.

Совместимость: Julia 1.2

Для этой функции требуется версия Julia не ниже 1.2.

См. также описание propertynames, hasfield.

# Core.getfieldFunction

getfield(value, name::Symbol, [order::Symbol])
getfield(value, i::Int, [order::Symbol])

Извлекает поле из составного объекта value по имени или позиции. При необходимости для этой операции можно указать порядок. Если поле объявлено с ключевым словом @atomic, настоятельно рекомендуется, чтобы указанный порядок был совместим с операциями сохранения в этом расположении. В противном случае, если объявление @atomic отсутствует и этот параметр указан, он должен быть :not_atomic. См. также описание getproperty и fieldnames.

Примеры

julia> a = 1//2
1//2

julia> getfield(a, :num)
1

julia> a.num
1

julia> getfield(a, 1)
1

# Core.setfield!Function

setfield!(value, name::Symbol, x, [order::Symbol])
setfield!(value, i::Int, x, [order::Symbol])

Присваивает x именованному полю объекта value составного типа. Объект value должен быть изменяемым, а x — подтипом fieldtype(typeof(value), name). Кроме того, для этой операции можно указать порядок. Если поле объявлено с ключевым словом @atomic, указывать порядок необходимо. В противном случае, если объявление @atomic отсутствует и этот параметр указан, он должен быть :not_atomic. См. также описание setproperty!.

Примеры

julia> mutable struct MyMutableStruct
           field::Int
       end

julia> a = MyMutableStruct(1);

julia> setfield!(a, :field, 2);

julia> getfield(a, :field)
2

julia> a = 1//2
1//2

julia> setfield!(a, :num, 3);
ERROR: setfield!: immutable struct of type Rational cannot be changed

# Core.isdefinedFunction

isdefined(m::Module, s::Symbol, [order::Symbol])
isdefined(object, s::Symbol, [order::Symbol])
isdefined(object, index::Int, [order::Symbol])

Проверяет, определена ли глобальная переменная или поле объекта. Аргументами могут быть модуль и символ, составной объект и имя поля (в виде символа) или индекс. При необходимости для этой операции можно указать порядок. Если поле объявлено с ключевым словом @atomic, настоятельно рекомендуется, чтобы указанный порядок был совместим с операциями сохранения в этом расположении. В противном случае, если объявление @atomic отсутствует и этот параметр указан, он должен быть :not_atomic.

Чтобы проверить, определен ли элемент массива, используйте вместо этого функцию isassigned.

См. также описание @isdefined.

Примеры

julia> isdefined(Base, :sum)
true

julia> isdefined(Base, :NonExistentMethod)
false

julia> a = 1//2;

julia> isdefined(a, 2)
true

julia> isdefined(a, 3)
false

julia> isdefined(a, :num)
true

julia> isdefined(a, :numerator)
false

# Core.getglobalFunction

getglobal(module::Module, name::Symbol, [order::Symbol=:monotonic])

Получает значение привязки name из модуля module. При необходимости для этой операции можно указать атомарное упорядочение, в противном случае по умолчанию будет использоваться монотонное.

Хотя доступ к привязкам модулей с помощью getfield все еще поддерживается для обеспечения совместимости, всегда следует отдавать предпочтение getglobal, поскольку getglobal позволяет контролировать атомарное упорядочение (getfield всегда является монотонным) и лучше обозначает цель кода как для пользователя, так и для компилятором.

Большинство пользователей не должны вызывать эту функцию напрямую. Во всех случаях, кроме очень специфических, следует использовать функцию getproperty или соответствующий синтаксис т. е. module.name).

Совместимость: Julia 1.9

Для этой функции требуется версия Julia не ниже 1.9.

См. также описание getproperty и setglobal!.

Примеры

julia> a = 1
1

julia> module M
       a = 2
       end;

julia> getglobal(@__MODULE__, :a)
1

julia> getglobal(M, :a)
2

# Core.setglobal!Function

setglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])

Задает или изменяет значение имени (name) привязки в модуле module на x. Преобразование типа не выполняется, поэтому если тип уже был объявлен для привязки, x должен иметь соответствующий тип, иначе возникнет ошибка.

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

Обычно пользователи обращаются к этой функциональности с помощью функции setproperty! или соответствующего синтаксиса (т. е. module.name = x), поэтому она предназначена только для очень специфических вариантов использования.

Совместимость: Julia 1.9

Для этой функции требуется версия Julia не ниже 1.9.

См. также описание setproperty! и getglobal.

Примеры

julia> module M end;

julia> M.a  # то же, что и `getglobal(M, :a)`
ERROR: UndefVarError: `a` not defined

julia> setglobal!(M, :a, 1)
1

julia> M.a
1

# Base.@isdefinedMacro

@isdefined s -> Bool

Проверяет, определена ли переменная s в текущей области.

См. также описание функции isdefined, которая проверяет свойства полей, функции isassigned, которая проверяет индексы массива, и функции haskey, которая проверяет другие сопоставления.

Примеры

julia> @isdefined newvar
false

julia> newvar = 1
1

julia> @isdefined newvar
true

julia> function f()
           println(@isdefined x)
           x = 3
           println(@isdefined x)
       end
f (generic function with 1 method)

julia> f()
false
true

# Base.convertFunction

convert(T, x)

Преобразует x в значение типа T.

Если T — целочисленный тип (Integer), возникает ошибка InexactError в случае, когда значение x не может быть представлено как тип T, например, если значение x не целочисленное или выходит за пределы диапазона, поддерживаемого типом T.

Примеры

julia> convert(Int, 3.0)
3

julia> convert(Int, 3.5)
ERROR: InexactError: Int64(3.5)
Stacktrace:
[...]

Если T — это тип AbstractFloat, возвращается ближайшее к x значение, поддерживаемое типом T.

julia> x = 1/3
0.3333333333333333

julia> convert(Float32, x)
0.33333334f0

julia> convert(BigFloat, x)
0.333333333333333314829616256247390992939472198486328125

Если T — это тип-коллекция, а x — коллекция, функция convert(T, x) может возвращать псевдоним для всего объекта x или его части.

julia> x = Int[1, 2, 3];

julia> y = convert(Vector{Int}, x);

julia> y === x
true

См. также описание round, trunc, oftype, reinterpret.

# Base.promoteFunction

promote(xs...)

Преобразует все аргументы в общий тип и возвращает их в виде кортежа. Если невозможно преобразовать ни один из аргументов, происходит ошибка.

См. также описание promote_type, promote_rule.

Примеры

julia> promote(Int8(1), Float16(4.5), Float32(4.1))
(1.0f0, 4.5f0, 4.1f0)

julia> promote_type(Int8, Float16, Float32)
Float32

julia> reduce(Base.promote_typejoin, (Int8, Float16, Float32))
Real

julia> promote(1, "x")
ERROR: promotion of types Int64 and String failed to change any arguments
[...]

julia> promote_type(Int, String)
Any

# Base.oftypeFunction

oftype(x, y)

Преобразует y в тип объекта x, т. е. convert(typeof(x), y).

Примеры

julia> x = 4;

julia> y = 3.;

julia> oftype(x, y)
3

julia> oftype(y, x)
4.0

# Base.widenFunction

widen(x)

Если x — это тип, возвращает более широкий тип, то есть такой, что арифметические операции + и - гарантированно выполняются без переполнения и потери точности для любого сочетания значений, поддерживаемых типом x.

Для целочисленных типов фиксированного размера длиной менее 128 битов функция widen возвращает тип с удвоенным количеством битов.

Если x — это значение, оно преобразуется в widen(typeof(x)).

Примеры

julia> widen(Int32)
Int64

julia> widen(1.5f0)
1.5

# Base.identityFunction

identity(x)

Функция тождественности. Возвращает свой аргумент.

См. также описание функций one и oneunit и оператора I из библиотеки LinearAlgebra.

Примеры

julia> identity("Well, what did you expect?")
"Well, what did you expect?"

Свойства типов

Отношения типов

# Base.supertypeFunction

supertype(T::DataType)

Возвращает супертип типа данных T.

Примеры

julia> supertype(Int32)
Signed

# Core.TypeType

Core.Type{T}

Core.Type — это абстрактный тип, экземплярами которого являются все объекты типов. Единственный экземпляр одинарного типа Core.Type{T} — объект T.

Примеры

julia> isa(Type{Float64}, Type)
true

julia> isa(Float64, Type)
true

julia> isa(Real, Type{Float64})
false

julia> isa(Real, Type{Real})
true

# Core.DataTypeType

DataType <: Type{T}

DataType представляет явно объявленные типы с именами, явно объявленными супертипами и (необязательно) параметрами. Каждое конкретное значение в системе является экземпляром какого-либо типа DataType.

Примеры

julia> typeof(Real)
DataType

julia> typeof(Int)
DataType

julia> struct Point
           x::Int
           y
       end

julia> typeof(Point)
DataType

# Core.:<:Function

<:(T1, T2)

Оператор подтипа: возвращает true тогда и только тогда, когда все значения типа T1 также относятся к типу T2.

Примеры

julia> Float64 <: AbstractFloat
true

julia> Vector{Int} <: AbstractArray
true

julia> Matrix{Float64} <: Matrix{AbstractFloat}
false

# Base.:>:Function

>:(T1, T2)

Оператор супертипа, эквивалентен T2 <: T1.

# Base.typejoinFunction

typejoin(T, S, ...)

Возвращает ближайшего общего предка типов T и S, то есть самый узкий тип, от которого они оба наследуются. Выполняет рекурсию по дополнительным аргументам с переменным количеством.

Примеры

julia> typejoin(Int, Float64)
Real

julia> typejoin(Int, Float64, ComplexF32)
Number

# Base.typeintersectFunction

typeintersect(T::Type, S::Type)

Вычисляет тип, который содержит пересечение типов T и S. Обычно это наиболее узкий такой тип или ближайший к нему.

# Base.promote_typeFunction

promote_type(type1, type2, ...)

Под продвижением понимается преобразование значений смешанных типов в один общий тип. promote_type представляет способ продвижения по умолчанию в Julia, когда операторы (обычно математические) получают аргументы разных типов. Как правило, функция promote_type пытается вернуть тип, который позволяет по крайней мере приблизительно выразить большинство значений каждого из входных типов без излишнего расширения. Некоторые потери допустимы. Например, promote_type(Int64, Float64) возвращает Float64, хотя, строго говоря, не все значения Int64 можно представить точно как значения Float64.

См. также описание promote, promote_typejoin, promote_rule.

Примеры

julia> promote_type(Int64, Float64)
Float64

julia> promote_type(Int32, Int64)
Int64

julia> promote_type(Float32, BigInt)
BigFloat

julia> promote_type(Int16, Float16)
Float16

julia> promote_type(Int64, Float16)
Float16

julia> promote_type(Int8, UInt16)
UInt16

Чтобы перегрузить продвижение для собственного типа, следует перегрузить функцию promote_rule. Функция promote_rule вызывается внутри promote_type для определения типа. Если перегрузить promote_type напрямую, могут происходить ошибки вследствие неоднозначности.

# Base.promote_ruleFunction

promote_rule(type1, type2)

Указывает, какой тип должна использовать функция promote при передаче значений типов type1 и type2. Эту функцию не следует вызывать напрямую: добавляйте в нее необходимые определения для новых типов.

# Base.promote_typejoinFunction

promote_typejoin(T, S)

Вычисляет тип, который содержит как тип T, так и тип S. Результирующий тип может быть либо родителем обоих входных типов, либо их объединением (Union). Использует typejoin как резервный вариант.

См. также описание функций promote и promote_type.

Примеры

julia> Base.promote_typejoin(Int, Float64)
Real

julia> Base.promote_type(Int, Float64)
Float64

# Base.isdispatchtupleFunction

isdispatchtuple(T)

Определяет, является ли тип T «конечным типом» кортежа, то есть может использоваться в качестве сигнатуры типа при диспетчеризации и не имеет подтипов (или супертипов), которые могли бы использоваться в вызове.

Объявленная структура

# Base.ismutableFunction

ismutable(v) -> Bool

Возвращает true тогда и только тогда, когда значение v изменяемое. В разделе Изменяемые составные типы подробно рассматривается понятие изменяемости. Обратите внимание, что эта функция работает со значениями, поэтому если передать ей тип DataType, она определит, что значение типа изменяемое.

См. также описание isbits и isstructtype.

Примеры

julia> ismutable(1)
false

julia> ismutable([1,2])
true
Совместимость: Julia 1.5

Для этой функции требуется версия Julia не ниже 1.5.

# Base.isimmutableFunction

isimmutable(v) -> Bool

Рекомендуем использовать вместо этого функцию !ismutable(v), так как функция isimmutable(v) будет заменена функцией !ismutable(v) в будущей версии. (Начиная с версии Julia 1.5) Возвращает true, если значение v неизменяемое. В разделе Изменяемые составные типы подробно рассматривается понятие изменяемости. Обратите внимание, что эта функция работает со значениями, поэтому если передать ей тип, она определит, что значение типа DataType изменяемое.

Примеры

julia> isimmutable(1)
true

julia> isimmutable([1,2])
false

# Base.ismutabletypeFunction

ismutabletype(T) -> Bool

Определяет, был ли тип T объявлен как изменяемый (т. е. с помощью ключевого слова mutable struct).

Совместимость: Julia 1.7

Для этой функции требуется версия Julia не ниже 1.7.

# Base.isabstracttypeFunction

isabstracttype(T)

Определяет, был ли тип T объявлен как абстрактный (т. е. с помощью синтаксиса abstract type).

Примеры

julia> isabstracttype(AbstractArray)
true

julia> isabstracttype(Vector)
false

# Base.isprimitivetypeFunction

isprimitivetype(T) -> Bool

Определяет, был ли тип T объявлен как примитивный (т. е. с помощью синтаксиса primitive type).

# Base.issingletontypeFunction

Base.issingletontype(T)

Определяет, может ли у типа T быть только один экземпляр, как, например, в случае с типом структуры без полей.

# Base.isstructtypeFunction

isstructtype(T) -> Bool

Определяет, был ли тип T объявлен как тип структуры (то есть с ключевым словом struct или mutable struct).

# Base.nameofMethod

nameof(t::DataType) -> Symbol

Возвращает имя типа DataType (возможно, инкапсулированного в UnionAll, без имени родительского модуля) в виде символа.

Примеры

julia> module Foo
           struct S{T}
           end
       end
Foo

julia> nameof(Foo.S{T} where T)
:S

# Base.fieldnamesFunction

fieldnames(x::DataType)

Возвращает кортеж с именами полей типа DataType.

См. также описание propertynames и hasfield.

Примеры

julia> fieldnames(Rational)
(:num, :den)

julia> fieldnames(typeof(1+im))
(:re, :im)

# Base.fieldnameFunction

fieldname(x::DataType, i::Integer)

Возвращает имя поля с индексом i типа DataType.

Примеры

julia> fieldname(Rational, 1)
:num

julia> fieldname(Rational, 2)
:den

# Core.fieldtypeFunction

fieldtype(T, name::Symbol | index::Int)

Определяет объявленный тип поля (указанного по имени или индексу) в составном типе DataType T.

Примеры

julia> struct Foo
           x::Int64
           y::String
       end

julia> fieldtype(Foo, :x)
Int64

julia> fieldtype(Foo, 2)
String

# Base.fieldtypesFunction

fieldtypes(T::Type)

Возвращает объявленные типы всех полей составного типа DataType T в виде кортежа.

Совместимость: Julia 1.1

Для этой функции требуется версия Julia не ниже 1.1.

Примеры

julia> struct Foo
           x::Int64
           y::String
       end

julia> fieldtypes(Foo)
(Int64, String)

# Base.fieldcountFunction

fieldcount(t::Type)

Возвращает количество полей, которое будет иметь экземпляр указанного типа. Если тип слишком абстрактный для определения этого значения, происходит ошибка.

# Base.hasfieldFunction

hasfield(T::Type, name::Symbol)

Возвращает логическое значение, указывающее, есть ли у типа T собственное поле name.

См. также описание функций fieldnames, fieldcount и hasproperty.

Совместимость: Julia 1.2

Для этой функции требуется версия Julia не ниже 1.2.

Примеры

julia> struct Foo
            bar::Int
       end

julia> hasfield(Foo, :bar)
true

julia> hasfield(Foo, :x)
false

# Core.nfieldsFunction

nfields(x) -> Int

Возвращает количество полей у указанного объекта.

Примеры

julia> a = 1//2;

julia> nfields(a)
2

julia> b = 1
1

julia> nfields(b)
0

julia> ex = ErrorException("I've done a bad thing");

julia> nfields(ex)
1

В этим примерах a имеет тип Rational, у которого два поля. Поле b имеет тип Int — примитивный битовый тип без полей. Поле ex имеет тип ErrorException с одним полем.

# Base.isconstFunction

isconst(m::Module, s::Symbol) -> Bool

Определяет, объявлена ли глобальная переменная как const в модуле m.

isconst(t::DataType, s::Union{Int,Symbol}) -> Bool

Определяет, объявлено ли поле s как const в типе t.

Расположение в памяти

# Base.sizeofMethod

sizeof(T::DataType)
sizeof(obj)

Размер в байтах канонического двоичного представления указанного типа DataType T, если таковое имеется. Либо размер в байтах объекта obj, если он не относится к типу DataType.

См. также описание Base.summarysize.

Примеры

julia> sizeof(Float32)
4

julia> sizeof(ComplexF64)
16

julia> sizeof(1.0)
8

julia> sizeof(collect(1.0:10.0))
80

julia> struct StructWithPadding
           x::Int64
           flag::Bool
       end

julia> sizeof(StructWithPadding) # не сумма `sizeof` полей из-за заполнения
16

julia> sizeof(Int64) + sizeof(Bool) # отличается от приведенного выше
9

Если тип DataType T не имеет определенного размера, возникает ошибка.

julia> sizeof(AbstractArray)
ERROR: Abstract type AbstractArray does not have a definite size.
Stacktrace:
[...]

# Base.isconcretetypeFunction

isconcretetype(T)

Определяет, является ли тип T конкретным, то есть может иметь непосредственные экземпляры (значения x такие, что typeof(x) === T).

См. также описание isbits, isabstracttype, issingletontype.

Примеры

julia> isconcretetype(Complex)
false

julia> isconcretetype(Complex{Float32})
true

julia> isconcretetype(Vector{Complex})
true

julia> isconcretetype(Vector{Complex{Float32}})
true

julia> isconcretetype(Union{})
false

julia> isconcretetype(Union{Int,String})
false

# Base.isbitsFunction

isbits(x)

Возвращает true, если x является экземпляром типа isbitstype.

# Base.isbitstypeFunction

isbitstype(T)

Возвращает true, если T — это простой тип данных, то есть неизменяемый и не содержащий ссылок на другие значения, кроме значений типов primitive и isbitstype. Классический пример — числовые типы, такие как UInt8, Float64 и Complex{Float64}. Эта категория типов имеет особое значение, так как они могут использоваться как параметры типа, могут не отслеживать состояние isdefined или isassigned и имеют определенную структуру, совместимую с языком C.

См. также описание функций isbits, isprimitivetype и ismutable.

Примеры

julia> isbitstype(Complex{Float64})
true

julia> isbitstype(Complex)
false

# Base.fieldoffsetFunction

fieldoffset(type, i)

Возвращает байтовое смещение поля с индексом i типа относительно начала данных. Например, с помощью этой функции можно получить сводную информацию о структуре следующим образом.

julia> structinfo(T) = [(fieldoffset(T,i), fieldname(T,i), fieldtype(T,i)) for i = 1:fieldcount(T)];

julia> structinfo(Base.Filesystem.StatStruct)
13-element Vector{Tuple{UInt64, Symbol, Type}}:
 (0x0000000000000000, :desc, Union{RawFD, String})
 (0x0000000000000008, :device, UInt64)
 (0x0000000000000010, :inode, UInt64)
 (0x0000000000000018, :mode, UInt64)
 (0x0000000000000020, :nlink, Int64)
 (0x0000000000000028, :uid, UInt64)
 (0x0000000000000030, :gid, UInt64)
 (0x0000000000000038, :rdev, UInt64)
 (0x0000000000000040, :size, Int64)
 (0x0000000000000048, :blksize, Int64)
 (0x0000000000000050, :blocks, Int64)
 (0x0000000000000058, :mtime, Float64)
 (0x0000000000000060, :ctime, Float64)

# Base.datatype_alignmentFunction

Base.datatype_alignment(dt::DataType) -> Int

Минимальное выравнивание выделенной области памяти для экземпляров этого типа. Может вызываться для любого типа isconcretetype.

# Base.datatype_haspaddingFunction

Base.datatype_haspadding(dt::DataType) -> Bool

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

# Base.datatype_pointerfreeFunction

Base.datatype_pointerfree(dt::DataType) -> Bool

Определяет, могут ли экземпляры этого типа содержать ссылки на память, контролируемую сборщиком мусора. Может вызываться для любого типа isconcretetype.

Особые значения

# Base.typeminFunction

typemin(T)

Минимальное значение, которое может быть представлено указанным (вещественным) числовым типом DataType T.

См. также описание floatmin, typemax, eps.

Примеры

julia> typemin(Int8)
-128

julia> typemin(UInt32)
0x00000000

julia> typemin(Float16)
-Inf16

julia> typemin(Float32)
-Inf32

julia> nextfloat(-Inf32)  # минимальное конечное число с плавающей запятой типа Float32
-3.4028235f38

# Base.typemaxFunction

typemax(T)

Максимальное значение, которое может быть представлено указанным (вещественным) числовым типом DataType.

См. также описание floatmax, typemin, eps.

Примеры

julia> typemax(Int8)
127

julia> typemax(UInt32)
0xffffffff

julia> typemax(Float64)
Inf

julia> typemax(Float32)
Inf32

julia> floatmax(Float32)  # максимальное конечное число с плавающей запятой типа Float32
3.4028235f38

# Base.floatminFunction

floatmin(T = Float64)

Возвращает минимальное положительное нормальное число, которое может быть представлено типом с плавающей запятой T.

Примеры

julia> floatmin(Float16)
Float16(6.104e-5)

julia> floatmin(Float32)
1.1754944f-38

julia> floatmin()
2.2250738585072014e-308

# Base.floatmaxFunction

floatmax(T = Float64)

Возвращает максимальное конечное число, которое может быть представлено типом с плавающей запятой T.

См. также описание typemax, floatmin, eps.

Примеры

julia> floatmax(Float16)
Float16(6.55e4)

julia> floatmax(Float32)
3.4028235f38

julia> floatmax()
1.7976931348623157e308

julia> typemax(Float64)
Inf

# Base.maxintfloatFunction

maxintfloat(T=Float64)

Максимальное последовательное целое число с плавающей запятой, которое может быть точно представлено указанным типом с плавающей запятой T (по умолчанию Float64).

Иначе говоря, функция maxintfloat возвращает минимальное положительное целое число с плавающей запятой n такое, что n+1 не может быть точно представлено типом T.

Если требуется значение целочисленного типа (Integer), используйте Integer(maxintfloat(T)).

maxintfloat(T, S)

Максимальное последовательное целое число, которое может быть представлено указанным типом с плавающей запятой T и не больше максимального целого числа, которое может быть представлено целочисленным типом S. Или, что то же самое, это минимальное из значений maxintfloat(T) и typemax(S).

# Base.epsMethod

eps(::Type{T}) where T<:AbstractFloat
eps()

Возвращает машинный эпсилон типа с плавающей запятой T (T = Float64 по умолчанию). Определяется как промежуток между 1 и следующим максимальным значением, которое может быть представлено типом typeof(one(T)). Эквивалентно eps(one(T)). (Так как значение eps(T) — это граница относительной погрешности для типа T, оно представляет собой безразмерную величину, так же как one.)

Примеры

julia> eps()
2.220446049250313e-16

julia> eps(Float32)
1.1920929f-7

julia> 1.0 + eps()
1.0000000000000002

julia> 1.0 + eps()/2
1.0

# Base.epsMethod

eps(x::AbstractFloat)

Возвращает единицу наименьшей точности (ulp) для значения x. Это расстояние между идущими подряд представимыми значениями с плавающей запятой при значении x. В большинстве случаев, если расстояние по двум сторонам от x разное, берется большее из них, то есть

eps(x) == max(x-prevfloat(x), nextfloat(x)-x)

Исключениями из этого правила являются минимальное и максимальное конечные значения (например, nextfloat(-Inf) и prevfloat(Inf) для типа Float64), для которых округление производится до меньшего из расстояний.

Обосновывается это тем, что функция eps ограничивает погрешность округления ошибка. В режиме округления по умолчанию RoundNearest, если  — вещественное число, а  — число с плавающей запятой, ближайшее к , то

См. также описание nextfloat, issubnormal, floatmax.

Примеры

julia> eps(1.0)
2.220446049250313e-16

julia> eps(prevfloat(2.0))
2.220446049250313e-16

julia> eps(2.0)
4.440892098500626e-16

julia> x = prevfloat(Inf)      # максимальное конечное значение Float64
1.7976931348623157e308

julia> x + eps(x)/2            # округление в большую сторону
Inf

julia> x + prevfloat(eps(x)/2) # округление в меньшую сторону
1.7976931348623157e308

# Base.instancesFunction

instances(T::Type)

Возвращает коллекцию всех экземпляров указанного типа, если применимо. Используется в основном для перечислимых типов (см. @enum).

Пример

julia> @enum Color red blue green

julia> instances(Color)
(red, blue, green)

Особые типы

# Core.AnyType

Any::DataType

Any — это объединение всех типов. Имеет характерное свойство isa(x, Any) == true для любого x. Таким образом, Any описывает всю совокупность возможных значений. Например, Integer является подмножеством типа Any, включающим Int, Int8 и другие целочисленные типы.

# Core.UnionType

Union{Types...}

Объединение типов — это абстрактный тип, который включает в себя все экземпляры всех типов-аргументов. Пустое объединение Union{} является низшим типом в Julia.

Примеры

julia> IntOrString = Union{Int,AbstractString}
Union{Int64, AbstractString}

julia> 1 isa IntOrString
true

julia> "Hello!" isa IntOrString
true

julia> 1.0 isa IntOrString
false

# Union{}Keyword

Union{}

Union{}, то есть пустое объединение (Union) типов, — это тип без значений. Оно имеет характерное свойство isa(x, Union{}) == false для любого x. Для объединения Union{} определен псевдоним Base.Bottom, а его тип — Core.TypeofBottom.

Примеры

julia> isa(nothing, Union{})
false

# Core.UnionAllType

UnionAll

Объединение типов по всем значениям параметра типа. UnionAll используется для описания параметрических типов, у которых значения некоторых параметров неизвестны.

Примеры

julia> typeof(Vector)
UnionAll

julia> typeof(Vector{Int})
DataType

# Core.TupleType

Tuple{Types...}

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

Типы кортежей ковариантны по своим параметрам: Tuple{Int} является подтипом Tuple{Any}. Поэтому Tuple{Any} считается абстрактным типом, а типы кортежей являются конкретными, только если таковыми являются их параметры. У кортежей нет имен полей; поля доступны только по индексам.

См. раздел руководства, посвященный типам кортежей.

См. также Vararg, NTuple, tuple, NamedTuple.

# Core.NTupleType

NTuple{N, T}

Компактный способ представления типа кортежа длиной N, все элементы которого относятся к типу T.

Примеры

julia> isa((1, 2, 3, 4, 5, 6), NTuple{6, Int})
true

# Core.NamedTupleType

NamedTuple

NamedTuple, как следует из названия, — это именованный кортеж (Tuple). То есть это подобная кортежу коллекция значений, каждый элемент которой имеет уникальное имя, представленное Symbol. Как и тип Tuple, тип NamedTuple является неизменяемым: ни имена, ни значения нельзя изменить напрямую после создания.

Получить доступ к значению, связанному с именем, в именованном кортеже можно с помощью синтаксиса доступа к полям, например x.a, или с помощью функции getindex, например x[:a] или x[(:a, :b)]. Кортеж имен можно получить с помощью функции keys, а кортеж значений — с помощью функции values.

При итерации по NamedTuple возвращаются значения без имен. (См. пример ниже.) Для итерации по парам имя-значение используйте функцию pairs.

Объявлять типы NamedTuple удобно с помощью макроса @NamedTuple.

Примеры

julia> x = (a=1, b=2)
(a = 1, b = 2)

julia> x.a
1

julia> x[:a]
1

julia> x[(:a,)]
(a = 1,)

julia> keys(x)
(:a, :b)

julia> values(x)
(1, 2)

julia> collect(x)
2-element Vector{Int64}:
 1
 2

julia> collect(pairs(x))
2-element Vector{Pair{Symbol, Int64}}:
 :a => 1
 :b => 2

Так же как и в случае с программным определением именованных аргументов, именованный кортеж можно создать путем указания пары name::Symbol => value или распаковки итератора, который создает такие пары, после точки с запятой внутри литерала кортежа:

julia> (; :a => 1)
(a = 1,)

julia> keys = (:a, :b, :c); values = (1, 2, 3);

julia> (; zip(keys, values)...)
(a = 1, b = 2, c = 3)

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

julia> x = 0
0

julia> t = (; x)
(x = 0,)

julia> (; t.x)
(x = 0,)
Совместимость: Julia 1.5

Начиная с версии Julia 1.5 для идентификаторов и точечных выражений доступны неявные имена.

Совместимость: Julia 1.7

Начиная с версии Julia 1.7 методы getindex могут использоваться с несколькими символами (Symbol).

# Base.@NamedTupleMacro

@NamedTuple{key1::Type1, key2::Type2, ...}
@NamedTuple begin key1::Type1; key2::Type2; ...; end

Этот макрос обеспечивает более удобный синтаксис для объявления типов NamedTuple. Он возвращает тип NamedTuple с указанными ключами и типами, что равносильно выражению NamedTuple{(:key1, :key2, ...), Tuple{Type1,Type2,...}}. Если объявление ::Type пропущено, предполагается тип Any. Форма begin ... end позволяет разносить объявления на несколько строк (так же как и в случае с объявлением struct). В остальном такая форма ничем не отличается.

Например, кортеж (a=3.1, b="hello") имеет тип NamedTuple{(:a, :b),Tuple{Float64,String}}. С помощью макроса @NamedTuple его можно объявить так:

julia> @NamedTuple{a::Float64, b::String}
NamedTuple{(:a, :b), Tuple{Float64, String}}

julia> @NamedTuple begin
           a::Float64
           b::String
       end
NamedTuple{(:a, :b), Tuple{Float64, String}}
Совместимость: Julia 1.5

Этот макрос впервые реализован в Julia 1.5.

# Base.ValType

Val(c)

Возвращает тип Val{c}(), который не содержит данных времени выполнения. Такие типы можно использовать для передачи информации между функциями посредством значения c, которое должно иметь тип isbits или Symbol. Целью такой конструкции является возможность диспетчеризации констант напрямую (во время компиляции) без необходимости проверять их значения во время выполнения.

Примеры

julia> f(::Val{true}) = "Good"
f (generic function with 1 method)

julia> f(::Val{false}) = "Bad"
f (generic function with 2 methods)

julia> f(Val(true))
"Good"

# Core.VarargConstant

Vararg{T,N}

Последним параметром типа кортежа Tuple может быть специальное значение Vararg, которое означает любое количество элементов в конце. Выражению Vararg{T,N} соответствует ровно N элементов типа T. Наконец, выражению Vararg{T} соответствует ноль или более элементов типа T. Типы кортежей с параметром Vararg служат для представления аргументов, принимаемых методами с переменным числом аргументов (см. раздел руководства, посвященный функциям с переменным числом аргументов).

См. также описание NTuple.

Примеры

julia> mytupletype = Tuple{AbstractString, Vararg{Int}}
Tuple{AbstractString, Vararg{Int64}}

julia> isa(("1",), mytupletype)
true

julia> isa(("1",1), mytupletype)
true

julia> isa(("1",1,2), mytupletype)
true

julia> isa(("1",1,2,3.0), mytupletype)
false

# Core.NothingType

Nothing

Тип без полей, являющийся типом константы nothing.

См. также описание isnothing, Some, Missing.

# Base.isnothingFunction

isnothing(x)

Возвращает true, если x === nothing, и false в противном случае.

Совместимость: Julia 1.1

Для этой функции требуется версия Julia не ниже 1.1.

См. также описание функций something, Base.notnothing и ismissing.

# Base.notnothingFunction

notnothing(x)

Вызывает ошибку, если x === nothing, и возвращает x в противном случае.

# Base.SomeType

Some{T}

Тип-оболочка, используемый в объединении Union{Some{T}, Nothing}, чтобы отличать отсутствие значения (nothing) от наличия значения nothing (то есть Some(nothing)).

Для доступа к значению, заключенному в объект Some, используйте функцию something.

# Base.somethingFunction

something(x...)

Возвращает первое из значений аргументов, не равное nothing, если таковое имеется. В противном случае возникает ошибка. Аргументы типа Some не упаковываются.

См. также описание функций coalesce, skipmissing и @something.

Примеры

julia> something(nothing, 1)
1

julia> something(Some(1), nothing)
1

julia> something(missing, nothing)
missing

julia> something(nothing, nothing)
ERROR: ArgumentError: No value arguments present

# Base.@somethingMacro

@something(x...)

Сокращенная версия функции something.

Примеры

julia> f(x) = (println("f($x)"); nothing);

julia> a = 1;

julia> a = @something a f(2) f(3) error("Unable to find default for `a`")
1

julia> b = nothing;

julia> b = @something b f(2) f(3) error("Unable to find default for `b`")
f(2)
f(3)
ERROR: Unable to find default for `b`
[...]

julia> b = @something b f(2) f(3) Some(nothing)
f(2)
f(3)

julia> b === nothing
true
Совместимость: Julia 1.7

Этот макрос впервые реализован в Julia 1.7.

# Base.Enums.EnumType

Enum{T<:Integer}

Абстрактный супертип всех перечислимых типов, определенных с помощью макроса @enum.

# Base.Enums.@enumMacro

@enum EnumName[::BaseType] value1[=x] value2[=y]

Создает подтип Enum{BaseType} с именем EnumName и элементами перечисления value1 и value2, которым могут быть присвоены значения x и y соответственно. EnumName можно использовать так же, как любые другие типы, а значения элементов перечисления — как обычные значения.

Примеры

julia> @enum Fruit apple=1 orange=2 kiwi=3

julia> f(x::Fruit) = "I'm a Fruit with value: $(Int(x))"
f (generic function with 1 method)

julia> f(apple)
"I'm a Fruit with value: 1"

julia> Fruit(1)
apple::Fruit = 1

Элементы перечисления также можно указать внутри блока begin, например:

@enum EnumName begin
    value1
    value2
end

Базовый тип BaseType (по умолчанию Int32) должен быть примитивным подтипом типа Integer. Значения элементов можно преобразовывать между типом перечисления и BaseType. read и write выполняют эти преобразования автоматически. Если перечисление создано с типом BaseType, отличным от типа по умолчанию, Integer(value1) возвращает целочисленное значение value1 с типом BaseType.

Для получения списка всех экземпляров перечисления используйте функцию instances, например:

julia> instances(Fruit)
(apple, orange, kiwi)

Из экземпляра перечисления можно сконструировать символ:

julia> Symbol(apple)
:apple

# Core.ExprType

Expr(head::Symbol, args...)

Тип, представляющий составные выражения в проанализированном коде Julia (AST). Каждое выражение состоит из части head Symbol, в которой указывается тип выражения (например, вызов, цикл for, условный оператор и т. д.), и подвыражений (например, аргументов вызова). Подвыражения хранятся в поле Vector{Any} с именем args.

См. главу руководства о метапрограммировании и раздел документации для разработчиков, посвященный синтаксису AST в Julia.

Примеры

julia> Expr(:call, :+, 1, 2)
:(1 + 2)

julia> dump(:(a ? b : c))
Expr
  head: Symbol if
  args: Array{Any}((3,))
    1: Symbol a
    2: Symbol b
    3: Symbol c

# Core.SymbolType

Symbol

Тип объекта, используемый для представления идентификаторов в проанализированном коде Julia (AST). Также часто применяется в качестве имени или метки для идентификации сущности (например, как ключа словаря). Объект Symbol можно ввести с помощью оператора цитирования ::

julia> :name
:name

julia> typeof(:name)
Symbol

julia> x = 42
42

julia> eval(:x)
42

Объекты типа Symbol также можно создавать из строк или других значений путем вызова конструктора Symbol(x...).

Символы (Symbol) являются неизменяемыми, и в их реализации используется один и тот же объект для всех символов (Symbol) с одинаковым именем.

В отличие от строк, Symbol — это «атомарная» или «скалярная» сущность, которая не поддерживает итерацию по символам.

# Core.SymbolMethod

Symbol(x...) -> Symbol

Создает объект Symbol путем объединения строковых представлений аргументов.

Примеры

julia> Symbol("my", "name")
:myname

julia> Symbol("day", 4)
:day4

# Core.ModuleType

Module

Module (модуль) — это отдельная глобальная рабочая область переменных. Подробные сведения см. в описании ключевого слова module и разделе руководства, посвященном модулям.

Module(name::Symbol=:anonymous, std_imports=true, default_names=true)

Возвращает модуль с указанным именем. baremodule соответствует вызову Module(:ModuleName, false).

Пустой модуль, не содержащий ни одного имени, можно создать с помощью вызова Module(:ModuleName, false, false). В него не импортируются модули Base или Core, и он не содержит ссылку на себя.

Универсальные функции

# Core.FunctionType

Function

Абстрактный тип для всех функций.

Примеры

julia> isa(+, Function)
true

julia> typeof(sin)
typeof(sin) (singleton type of function sin, subtype of Function)

julia> ans <: Function
true

# Base.hasmethodFunction

hasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool

Определяет, имеет ли заданная универсальная функция метод, соответствующий указанному кортежу (Tuple) типов аргументов, с верхней границей «возраста мира» (иерархии определения методов), указанной в аргументе world.

Если предоставлен кортеж имен именованных аргументов kwnames, также проверяется наличие у метода f, соответствующего типу t, этих имен. Если метод принимает переменное число именованных аргументов, например посредством kwargs..., все имена в kwnames считаются соответствующими. В противном случае указанные имена должны быть подмножеством именованных аргументов метода.

См. также описание applicable.

Совместимость: Julia 1.2

Для указания имен именованных аргументов требуется версия Julia не ниже 1.2.

Примеры

julia> hasmethod(length, Tuple{Array})
true

julia> f(; oranges=0) = oranges;

julia> hasmethod(f, Tuple{}, (:oranges,))
true

julia> hasmethod(f, Tuple{}, (:apples, :bananas))
false

julia> g(; xs...) = 4;

julia> hasmethod(g, Tuple{}, (:a, :b, :c, :d))  # g принимает произвольное число именованных аргументов
true

# Core.applicableFunction

applicable(f, args...) -> Bool

Определяет, имеет ли заданная универсальная функция метод, применимый к указанным аргументам.

См. также описание hasmethod.

Примеры

julia> function f(x, y)
           x + y
       end;

julia> applicable(f, 1)
false

julia> applicable(f, 1, 2)
true

# Base.isambiguousFunction

Base.isambiguous(m1, m2; ambiguous_bottom=false) -> Bool

Определяет, могут ли два метода m1 и m2 быть неоднозначными для некоторой сигнатуры вызова. Эта проверка проводится в контексте других методов той же функции: сами по себе методы m1 и m2 могут быть неоднозначными, но если определен третий метод, устраняющий неоднозначность, возвращается значение false. И наоборот, сами по себе методы m1 и m2 могут быть упорядоченными, но если третий метод не может быть отсортирован вместе с ними, в совокупности возникает неоднозначность.

Для параметрических типов именованный аргумент ambiguous_bottom определяет то, считается ли объединение Union{} неоднозначным пересечением параметров типа: при значении true оно считается неоднозначным, а при значении false — нет.

Примеры

julia> foo(x::Complex{<:Integer}) = 1
foo (generic function with 1 method)

julia> foo(x::Complex{<:Rational}) = 2
foo (generic function with 2 methods)

julia> m1, m2 = collect(methods(foo));

julia> typeintersect(m1.sig, m2.sig)
Tuple{typeof(foo), Complex{Union{}}}

julia> Base.isambiguous(m1, m2, ambiguous_bottom=true)
true

julia> Base.isambiguous(m1, m2, ambiguous_bottom=false)
false

# Core.invokeFunction

invoke(f, argtypes::Type, args...; kwargs...)

Вызывает метод заданной универсальной функции f, который соответствует указанным типам argtypes, с передачей аргументов args и именованных аргументов kwargs. Аргументы args должны соответствовать типам, указанным в argtypes, то есть автоматическое преобразование не производится. Эта функция позволяет вызвать метод, который является не самым специфичным, что полезно в случаях, когда явным образом требуется поведение более общего определения (часто в рамках реализации более специфичного метода той же функции).

При использовании invoke для вызова функций, которые написаны кем-то другим, будьте осторожны. Определение, используемое для указанных типов argtypes, зависит от внутренней реализации, если только явным образом не заявляется, что вызов с определенными типами argtypes является частью общедоступного API. Например, в приведенном ниже примере функции f1 и f2 обычно будут взаимозаменяемыми, так как при обычном вызове (не с помощью invoke) разницы между ними нет. Однако эта разница становится заметной при использовании invoke.

Примеры

julia> f(x::Real) = x^2;

julia> f(x::Integer) = 1 + invoke(f, Tuple{Real}, x);

julia> f(2)
5

julia> f1(::Integer) = Integer
       f1(::Real) = Real;

julia> f2(x::Real) = _f2(x)
       _f2(::Integer) = Integer
       _f2(_) = Real;

julia> f1(1)
Integer

julia> f2(1)
Integer

julia> invoke(f1, Tuple{Real}, 1)
Real

julia> invoke(f2, Tuple{Real}, 1)
Integer

# Base.@invokeMacro

@invoke f(arg::T, ...; kwargs...)

Обеспечивает удобный способ вызова invoke путем расширения @invoke f(arg1::T1, arg2::T2; kwargs...) в invoke(f, Tuple{T1,T2}, arg1, arg2; kwargs...). Если аннотация типа аргумента не указана, он заменяется типом Core.Typeof этого аргумента. Чтобы вызвать метод, аргумент которого не типизирован или явно типизирован как Any, аннотируйте аргумент с помощью ::Any.

Примеры

julia> @macroexpand @invoke f(x::T, y)
:(Core.invoke(f, Tuple{T, Core.Typeof(y)}, x, y))

julia> @invoke 420::Integer % Unsigned
0x00000000000001a4
Совместимость: Julia 1.7

Для этого макроса требуется версия Julia не ниже 1.7.

Совместимость: Julia 1.9

Этот макрос экспортируется начиная с версии Julia 1.9.

# Base.invokelatestFunction

invokelatest(f, args...; kwargs...)

Вызывает f(args...; kwargs...), но гарантирует выполнение самого последнего метода f . Это полезно в особых ситуациях, например при выполнении длительных циклов событий или функций обратного вызова, которые могут вызывать устаревшие версии функции f. (Недостаток в том, что функция invokelatest выполняется немного медленнее, чем прямой вызов, f и тип результата не может быть выведен компилятором.)

Совместимость: Julia 1.9

До версии Julia 1.9 эта функция не экспортировалась и вызывалась в форме Base.invokelatest.

# Base.@invokelatestMacro

@invokelatest f(args...; kwargs...)

Обеспечивает удобный способ вызова invokelatest. @invokelatest f(args...; kwargs...) просто расширяется в Base.invokelatest(f, args...; kwargs...).

Совместимость: Julia 1.7

Для этого макроса требуется версия Julia не ниже 1.7.

Совместимость: Julia 1.9

До версии Julia 1.9 этот макрос не экспортировался и вызывался в форме Base.@invokelatest.

# newKeyword

new, or new{A,B,...}

Специальная функция, доступная внутренним конструкторам и создающая новый объект типа. При использовании формы new{A,B,…​} значения параметров для параметрических типов указываются явным образом. Дополнительные сведения см. в разделе руководства, посвященном методам внутренних конструкторов .

# Base.:|>Function

|>(x, f)

Инфиксный оператор, применяющий функцию f к аргументу x. Это позволяет записать f(g(x)) в виде x |> g |> f. При использовании анонимных функций обычно требуется заключить определение в круглые скобки, чтобы получить нужную цепочку.

Примеры

julia> 4 |> inv
0.25

julia> [2, 3, 5] |> sum |> inv
0.1

julia> [0 1; 2 3] .|> (x -> x^2) |> sum
14

# Base.:∘Function

f ∘ g

Композиция функций: (f ∘ g)(args...; kwargs...) означает f(g(args...; kwargs...)). Символ можно добавить в REPL Julia (и большинство редакторов, настроенных соответствующим образом), введя \circ<tab>.

Композиция функций также возможна в префиксной форме: ∘(f, g) равносильно f ∘ g. Префиксная форма поддерживает композицию нескольких функций (∘(f, g, h) = f ∘ g ∘ h) и распаковку (∘(fs...)) для составления итерируемой коллекции функций. Последний аргумент для выполняется первым.

Совместимость: Julia 1.4

Для композиции нескольких функций требуется версия Julia не ниже 1.4.

Совместимость: Julia 1.5

Для композиции одной функции ∘(f) требуется версия Julia не ниже 1.5.

Совместимость: Julia 1.7

Для использования именованных аргументов требуется версия Julia не ниже 1.7.

Примеры

julia> map(uppercase∘first, ["apple", "banana", "carrot"])
3-element Vector{Char}:
 'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
 'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)
 'C': ASCII/Unicode U+0043 (category Lu: Letter, uppercase)

julia> (==(6)∘length).(["apple", "banana", "carrot"])
3-element BitVector:
 0
 1
 1

julia> fs = [
           x -> 2x
           x -> x-1
           x -> x/2
           x -> x+1
       ];

julia> ∘(fs...)(3)
2.0

См. также описание ComposedFunction и !f::Function.

# Base.ComposedFunctionType

ComposedFunction{Outer,Inner} <: Function

Представляет композицию двух вызываемых объектов outer::Outer и inner::Inner. То есть

ComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))

Для создания экземпляра типа ComposedFunction предпочтительнее использовать оператор композиции :

julia> sin ∘ cos === ComposedFunction(sin, cos)
true

julia> typeof(sin∘cos)
ComposedFunction{typeof(sin), typeof(cos)}

Составные части композиции хранятся в полях объекта ComposedFunction. Доступ к ним можно получить следующим образом.

julia> composition = sin ∘ cos
sin ∘ cos

julia> composition.outer === sin
true

julia> composition.inner === cos
true
Совместимость: Julia 1.6

Для использования типа ComposedFunction требуется версия Julia не ниже 1.6. В более ранних версиях оператор возвращает вместо этого анонимную функцию.

См. также описание .

# Base.splatFunction

splat(f)

Эквивалентно

    my_splat(f) = args->f(args...)

то есть если дана функция, возвращает новую функцию, которая принимает один аргумент и распаковывает его в исходную функцию. Это может быть полезно, если необходимо передать функцию с несколькими аргументами в контексте, когда ожидается один аргумент; но в качестве этого аргумента передается кортеж.

Пример использования:

julia> map(splat(+), zip(1:3,4:6))
3-element Vector{Int64}:
 5
 7
 9

julia> my_add = splat(+)
splat(+)

julia> my_add((1,2,3))
6

# Base.Fix1Type

Fix1(f, x)

Тип, представляющий функцию с двумя аргументами f, которая применяется частично: первый аргумент имеет фиксированное значение x. Иными словами, Fix1(f, x) действует аналогично y->f(x, y).

См. также описание Fix2.

# Base.Fix2Type

Fix2(f, x)

Тип, представляющий функцию с двумя аргументами f, которая применяется частично: второй аргумент имеет фиксированное значение x. Иными словами, Fix2(f, x) действует аналогично y->f(y, x).

Синтаксис

# Core.evalFunction

Core.eval(m::Module, expr)

Вычисляет выражение в указанном модуле и возвращает результат.

# Base.MainInclude.evalFunction

eval(expr)

Вычисляет выражение в глобальной области содержащего модуля. У каждого модуля Module (кроме объявленных с ключевым словом baremodule) есть собственное определение функции eval с одним аргументом, которое вычисляет выражения в этом модуле.

# Base.@evalMacro

@eval [mod,] ex

Вычисляет выражение со значениями, которые интерполированы в него с помощью функции eval. Если указаны два аргумента, первый содержит модуль, в котором должно быть произведено вычисление.

# Base.evalfileFunction

evalfile(path::AbstractString, args::Vector{String}=String[])

Загружает файл в анонимный модуль с помощью функции include, вычисляет все выражения и возвращает значение последнего. Необязательный аргумент args можно использовать для задания входных аргументов скрипта (т. е. глобальной переменной ARGS). Обратите внимание, что определения (например, методы, глобальные объекты) обрабатываются в анонимном модуле и не влияют на текущий модуль.

Пример

julia> write("testfile.jl", """
           @show ARGS
           1 + 1
""");

julia> x = evalfile("testfile.jl", ["ARG1", "ARG2"]);
ARGS = ["ARG1", "ARG2"]

julia> x
2

julia> rm("testfile.jl")

# Base.escFunction

esc(e)

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

# Base.@inboundsMacro

@inbounds(blk)

Отключает проверку границ массивов в выражениях.

В приведенном ниже примере проверка вхождения в диапазон при обращении к элементу i массива A пропускается для повышения производительности.

function sum(A::AbstractArray)
    r = zero(eltype(A))
    for i in eachindex(A)
        @inbounds r += A[i]
    end
    return r
end

При использовании макроса @inbounds могут возвращаться неверные результаты, происходить сбои или повреждение данных, если индекс выходит за границы массива. Пользователь должен проводить проверку вручную. Используйте макрос @inbounds только в том случае, если из локального контекста однозначно следует, что все обращения будут происходить в пределах границ. В частности, использование 1:length(A) вместо eachindex(A) в функции наподобие приведенной выше не является безопасным внутри границ, потому что 1 может не быть первым индексом A во всех пользовательских типах, являющихся подтипами AbstractArray.

# Base.@boundscheckMacro

@boundscheck(blk)

Помечает выражение blk как блок проверки границ, благодаря чему он может игнорироваться блоком @inbounds.

Функция, в которой определен блок @boundscheck, должна быть встроена в вызывающий объект, чтобы макрос @inbounds подействовал.

Примеры

julia> @inline function g(A, i)
           @boundscheck checkbounds(A, i)
           return "accessing ($A)[$i]"
       end;

julia> f1() = return g(1:2, -1);

julia> f2() = @inbounds return g(1:2, -1);

julia> f1()
ERROR: BoundsError: attempt to access 2-element UnitRange{Int64} at index [-1]
Stacktrace:
 [1] throw_boundserror(::UnitRange{Int64}, ::Tuple{Int64}) at ./abstractarray.jl:455
 [2] checkbounds at ./abstractarray.jl:420 [inlined]
 [3] g at ./none:2 [inlined]
 [4] f1() at ./none:1
 [5] top-level scope

julia> f2()
"accessing (1:2)[-1]"

Аннотация @boundscheck позволяет разработчику библиотеки разрешить другому коду игнорировать проверки границ с помощью макроса @inbounds. Как указано в его описании, перед использованием @inbounds необходимо убедиться в том, что обращения к массиву не будут выходить за его границы, исходя из доступной информации. Например, при обращении по индексам к элементам подкласса AbstractArray необходимо проверять индексы с помощью метода axes. Таким образом, аннотации @boundscheck следует добавлять в реализацию getindex или setindex!, только если вы уверены, что ошибок не возникнет.

# Base.@propagate_inboundsMacro

@propagate_inbounds

Предписывает компилятору встроить функцию, сохранив контекст вхождения в диапазон вызывающего объекта.

# Base.@inlineMacro

@inline

Дает компилятору указание на то, что эта функция может быть встроена.

Небольшие функции обычно не требуют аннотации @inline, так как компилятор встраивает их автоматически. Используя @inline для более сложных функций, можно дать компилятору дополнительный сигнал к их встраиванию.

Макрос @inline можно применять непосредственно перед определением или в теле функции.

# аннотирование полного определения
@inline function longdef(x)
    ...
end

# аннотирование краткого определения
@inline shortdef(x) = ...

# аннотирование анонимной функции, создаваемой с помощью блока `do`
f() do
    @inline
    ...
end
Совместимость: Julia 1.8

Для использования в теле функции требуется версия Julia не ниже 1.8.


@inline block

Дает компилятору указание на то, что вызовы внутри блока block могут быть встроены.

# Компилятор попытается встроить `f`
@inline f(...)

# Компилятор попытается встроить `f`, `g` и `+`
@inline f(...) + g(...)

Аннотация в месте вызова всегда имеет приоритет над аннотацией, применяемой к определению вызываемой функции:

@noinline function explicit_noinline(args...)
    # тело
end


let
    @inline explicit_noinline(args...) # будет встроено
end

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

```julia
@noinline let a0, b0 = ...
    a = @inline f(a0)  # компилятор попытается встроить этот вызов
    b = f(b0)          # компилятор НЕ будет пытаться встроить этот вызов
    return a, b
end
```

Хотя при наличии аннотации в месте вызова попытка встраивания будет предпринята без учета модели стоимости, есть вероятность, что встраивания не произойдет. В частности, не могут встраиваться рекурсивные вызовы, даже если они снабжены аннотацией @inline.

Совместимость: Julia 1.8

Для использования аннотаций в месте вызова требуется версия Julia не ниже 1.8.

# Base.@noinlineMacro

@noinline

Дает компилятору указание на то, что функцию встраивать не следует.

Небольшие функции обычно встраиваются автоматически. Применяя к ним макрос @noinline, можно предотвратить это.

Макрос @noinline можно применять непосредственно перед определением или в теле функции.

# аннотирование полного определения
@noinline function longdef(x)
    ...
end

# аннотирование краткого определения
@noinline shortdef(x) = ...

# аннотирование анонимной функции, создаваемой с помощью блока `do`
f() do
    @noinline
    ...
end
Совместимость: Julia 1.8

Для использования в теле функции требуется версия Julia не ниже 1.8.


@noinline block

Дает компилятору указание на то, что вызовы внутри блока block встраивать не следует.

# Компилятор попытается не встраивать `f`
@noinline f(...)

# Компилятор попытается не встраивать `f`, `g` и `+`
@noinline f(...) + g(...)

Аннотация в месте вызова всегда имеет приоритет над аннотацией, применяемой к определению вызываемой функции:

@inline function explicit_inline(args...)
    # тело
end


let
    @noinline explicit_inline(args...) # не будет встроено
end

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

```julia
@inline let a0, b0 = ...
    a = @noinline f(a0)  # компилятор НЕ будет пытаться встроить этот вызов
    b = f(b0)            # компилятор попытается встроить этот вызов
    return a, b
end
```
Совместимость: Julia 1.8

Для использования аннотаций в месте вызова требуется версия Julia не ниже 1.8.


Простейшая функция (например, возвращающая константу) может быть встроена, несмотря на аннотацию.

# Base.@nospecializeMacro

@nospecialize

При применении к имени аргумента функции дает компилятору указание на то, что метод не следует специализировать для разных типов этого аргумента: для каждого аргумента должен использоваться объявленный тип. Он может применяться к аргументу в формальном списке аргументов или в теле функции. При применении к аргументу макрос должен охватывать все его выражение, например @nospecialize(x::Real) или @nospecialize(i::Integer...), а не только имя аргумента. При использовании в теле функции макрос должен находиться в положении оператора перед остальным кодом.

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

Восстановить поведение специализации по умолчанию можно с помощью макроса @specialize.

function example_function(@nospecialize x)
    ...
end

function example_function(x, @nospecialize(y = 1))
    ...
end

function example_function(x, y, z)
    @nospecialize x y
    ...
end

@nospecialize
f(y) = [x for x in y]
@specialize

Макрос @nospecialize влияет на генерацию кода, но не на вывод: он ограничивает разнообразие итогового машинного кода, но не накладывает никаких ограничений (помимо стандартных) на вывод типов.

Пример

julia> f(A::AbstractArray) = g(A)
f (generic function with 1 method)

julia> @noinline g(@nospecialize(A::AbstractArray)) = A[1]
g (generic function with 1 method)

julia> @code_typed f([1.0])
CodeInfo(
1 ─ %1 = invoke Main.g(_2::AbstractArray)::Float64
└──      return %1
) => Float64

Здесь результатом аннотации @nospecialize является эквивалент

f(A::AbstractArray) = invoke(g, Tuple{AbstractArray}, A)

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

# Base.@specializeMacro

@specialize

Восстанавливает поведение специализации по умолчанию для аргумента. Подробные сведения см. в описании макроса @nospecialize.

# Base.gensymFunction

gensym([tag])

Создает символ, который не будет конфликтовать с другими именами переменных (в том же модуле).

# Base.@gensymMacro

@gensym

Создает символ gensym для переменной. Например, @gensym x y преобразовывается в x = gensym("x"); y = gensym("y").

# var"name"Keyword

var

Синтаксис var"example" позволяет обращаться к переменной с именем Symbol("example"), даже если example не является допустимым именем в Julia.

Это может быть полезно для совместимости с языками программирования, в которых действуют другие правила построения допустимых имен. Например, для обращения к переменной R с именем draw.segments можно использовать выражение var"draw.segments" в коде Julia.

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

Обратите внимание, что этот синтаксис требует поддержки анализатором, поэтому он расширяется непосредственно анализатором, а не реализуется как обычный строковый макрос @var_str.

Совместимость: Julia 1.3

Для использования этого синтаксиса требуется версия Julia не ниже 1.3.

# Base.@gotoMacro

@goto name

С помощью выражения @goto name производится безусловный переход к оператору в расположении @label name.

Макросы @label и @goto не позволяют переходить к другим операторам верхнего уровня. При попытке сделать это произойдет ошибка. Для использования @goto заключите макросы @label и @goto в блок.

# Base.@labelMacro

@label name

Присваивает оператору символьную метку name. Метка обозначает конечную точку безусловного перехода с помощью @goto name.

# Base.SimdLoop.@simdMacro

@simd

Помечает цикл for, сообщая компилятору, что он может более свободно переупорядочивать его.

Эта функция является экспериментальной и может измениться или исчезнуть в будущих версиях Julia. Неправильное использование макроса @simd может привести к непредвиденным результатам.

Объект, по которому осуществляется итерация в цикле @simd for, должен быть одномерным диапазоном. При использовании макроса @simd утверждается несколько свойств цикла.

  • Итерации можно безопасно выполнять в произвольном порядке или с перекрытием (операции с редукционными переменными имеют свои особенности).

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

Во многих случаях Julia может автоматически векторизовать внутренние циклы for без использования макроса @simd. Использование @simd дает компилятору дополнительную свободу, так что векторизация становится возможной и в других ситуациях. В любом случае для векторизации внутреннего цикла он должен обладать следующими свойствами.

  • Цикл должен быть наиболее глубоко вложенным.

  • Тело цикла должно представлять собой линейный код. Поэтому в настоящее время @inbounds требуется для всех обращений к массиву. Компилятор может иногда преобразовывать короткие выражения &&, || и ?: в линейный код, если можно безопасно вычислить все операнды без условий. Можно также использовать функцию ifelse. вместо ?: в цикле, если это безопасно.

  • Обращения должны иметь пошаговый характер: операции «сборки» (чтения по произвольному индексу) и «распределения» (записи по произвольному индексу) недопустимы.

  • Шаг массива должен быть единичным.

Макрос @simd по умолчанию не утверждает, что цикл полностью лишен циклически порожденных зависимостей в памяти: в обобщенном коде это допущение может легко нарушаться. Если вы пишете необобщенный код, то можете использовать @simd ivdep for ... end для утверждения следующих дополнительных условий.

  • В памяти нет циклически порожденных зависимостей.

  • Любая итерация может продвигаться вперед, не дожидаясь завершения предыдущей итерации.

# Base.@pollyMacro

@polly

Предписывает компилятору применить к функции полиэдрический оптимизатор Polly.

# Base.@generatedMacro

@generated f

@generated помечает функцию как генерируемую. В теле генерируемой функции доступны только типы аргументов (но не их значения). Функция возвращает цитируемое выражение, которое вычисляется при вызове функции. Макрос @generated не следует применять к функциям, изменяющим глобальную область или зависящим от изменяемых элементов.

Дополнительные сведения см. в главе о метапрограммировании.

Примеры

julia> @generated function bar(x)
           if x <: Integer
               return :(x ^ 2)
           else
               return :(x)
           end
       end
bar (generic function with 1 method)

julia> bar(4)
16

julia> bar("baz")
"baz"

# Base.@pureMacro

@pure ex

Макрос @pure дает компилятору указание определить чистую функцию, что облегчает вывод типов.

Этот макрос предназначен для внутреннего использования компилятором и может быть изменен.

В версии Julia 1.8 и более поздних предпочтительнее использовать @assume_effects вместо @pure. Причина в том, что макрос @assume_effects обеспечивает более детальный контроль над моделью чистоты в Julia, а система побочных эффектов дает большой простор для оптимизаций.

# Base.@assume_effectsMacro

@assume_effects setting... ex

Макрос @assume_effects переопределяет модель побочных эффектов компилятора для указанного метода. ex должно быть определением метода или выражением @ccall.

Совместимость: Julia 1.8

Для использования Base.@assume_effects требуется версия Julia 1.8.

Примеры

julia> Base.@assume_effects :terminates_locally function pow(x)
           # :terminates_locally обеспечивает свертку констант в `pow`
           res = 1
           1 < x < 20 || error("bad pow")
           while x > 1
               res *= x
               x -= 1
           end
           return res
       end
pow (generic function with 1 method)

julia> code_typed() do
           pow(12)
       end
1-element Vector{Any}:
 CodeInfo(
1 ─     return 479001600
) => Int64

julia> Base.@assume_effects :total !:nothrow @ccall jl_type_intersection(Vector{Int}::Any, Vector{<:Integer}::Any)::Any
Vector{Int64} (alias for Array{Int64, 1})

Неправильное использование этого макроса может привести к неопределенному поведению (включая сбои, неверные результаты или другие трудно отслеживаемые ошибки). Используйте его с осторожностью и только как крайнее средство в случае абсолютной необходимости. Даже в таких случаях СЛЕДУЕТ предпринять все возможные меры, чтобы минимизировать категоричность утверждения эффекта (например, не используйте :total, если будет достаточно :nothrow).

Как правило, каждое значение setting делает утверждение о поведении функции, не требуя от компилятора подтверждения такого значения. Такие утверждения делаются для всех «возрастов мира». Поэтому рекомендуется избегать использования универсальных функций, которые позднее могут быть расширены так, что утверждения станут недействительными (что приведет к неопределенному поведению).

Поддерживаются следующие значения setting:

  • :consistent

  • :effect_free

  • :nothrow

  • :terminates_globally

  • :terminates_locally

  • :notaskstate

  • :inaccessiblememonly

  • :foldable

  • :total

Расширенная справка


:consistent

Значение :consistent утверждает следующее для идентичных входных данных (===):

  • способ завершения выполнения (возврат значения, вызов исключения, выполнение не завершается) всегда будет одинаковым;

  • если метод возвращает управление, результаты всегда будут идентичными.

В частности, из этого следует, что метод не должен возвращать только что выделенный изменяемый объект. Изменяемые объекты, хранящиеся в разных местах в памяти, не являются идентичными, даже если их содержимое идентично.

Утверждение :consistent делается с учетом «возраста мира». Более формально это выражается так: если есть для вычисления в «возрасте мира» , должно быть верно следующее:

∀ i, x, y: x ≡ y → fᵢ(x) ≡ fᵢ(y)

Однако для двух «возрастов мира» , , таких что , возможно, что .

Из этого далее следует, что возвращаемые значения функций :consistent не должны зависеть от состояния кучи или любого другого состояния, которое не является постоянным для данного «возраста мира».

Утверждение согласованности :consistent распространяется на все допустимые переработки кода, производимые оптимизатором. Например, операции fastmath с плавающей запятой не считаются соответствующими утверждению :consistent, так как оптимизатор может переработать их, в результате чего выходные данные не будут согласованными (:consistent) даже для одного и того же «возраста мира» (например, потому, что одна операция была выполнена в интерпретаторе, а другая — оптимизирована).

Если выполнение функций :consistent завершается исключением, это исключение само по себе не требуется для удовлетворения изложенного выше требования идентичности.


:effect_free

Значение :effect_free утверждает, что метод лишен внешне семантически видимых побочных эффектов. Вот неполный список таких эффектов:

  • изменение значения глобальной переменной;

  • изменение кучи (например, массива или изменяемого значения), кроме указанных ниже случаев;

  • изменение таблицы методов (например, путем вызова функции eval);

  • операции ввод-вывода (файловые, сетевые и т. д.);

  • переключение задач.

Однако следующие побочные эффекты не являются явно семантически видимыми, даже если они могут наблюдаться:

  • выделение памяти (как для изменяемых, так и для неизменяемых объектов);

  • истекшее время;

  • сборка мусора;

  • изменение объектов в куче, время существования которых не превышает времени выполнения метода (то есть они были размещены в памяти в методе и не покидают его);

  • возврат значения (которое видно извне, но не является побочным эффектом).

Попросту говоря, видимый извне побочный эффект — это то, что повлияло бы на выполнение остальной программы, если функция не была бы выполнена.

Утверждение :effect_free делается как в отношении самого метода, так и в отношении всего выполняемого им кода. Учтите, что это утверждение должно соблюдаться для всех «возрастов мира», поэтому его следует применять ограниченно.


:nothrow

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

Внутри методов с аннотацией :nothrow можно использовать обработку исключений, но исключение не должно передаваться из самого метода.

MethodErrors и аналогичные исключения считаются завершением с ошибкой.


:terminates_globally

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

Утверждение :terminates_globally распространяется на все остальные методы, вызываемые аннотированным методом.

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


:terminates_locally

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

Утверждение :terminates_globally подразумевает :terminates_locally.


:notaskstate

Параметр :notaskstate утверждает, что метод не использует или не изменяет состояние локальной задачи (локальное хранилище задачи, состояние RNG и т. д.) и поэтому может безопасно перемещаться между задачами без заметных результатов.

Реализация обработки исключений предполагает использование состояния, хранящегося в объекте задачи. Однако в настоящее время это состояние не считается входящим в область :notaskstate и отслеживается отдельно с помощью эффекта :nothrow .

Утверждение :notaskstate относится к состоянию текущей выполняющейся задачи. Если ссылка на объект Task получена каким-либо иным способом, не учитывающим то, как задача выполняется в настоящее время, эффект :notaskstate не требуется «загрязнять». Это верно и в том случае, если объект задачи программно идентичен (===) текущей выполняющейся задаче.

Доступ к состоянию задачи обычно также приводит к «загрязнению» других эффектов, таких как :effect_free (при изменении состояния задачи) или :consistent (при использовании состояния задачи в вычислении результата). В частности, код без :notaskstate, но с :effect_free и :consistent может предусматривать устранение недостижимого кода и поэтому продвигаться до :total.


:inaccessiblememonly

Параметр :inaccessiblememonly утверждает, что метод не получает доступ или не изменяет доступную извне изменяемую память. Это означает, что метод может получить доступ или изменить изменяемую память для вновь выделенных объектов, которая недоступна другим методам или выполнению верхнего уровня до возврата из метода, но он не может получить доступ или изменить любое изменяемое глобальное состояние или изменяемую память, на которую указывают его аргументы.

Вот неполный список примеров, в которых такое предположение недействительно:

  • глобальная ссылка или вызов getglobal для доступа к изменяемой глобальной переменной;

  • глобальное присваивание или вызов setglobal! для выполнения присваивания неконстантной глобальной переменной;

  • вызов setfield!, который изменяет поле глобальной изменяемой переменной.

Утверждение :inaccessiblememonly распространяется на все остальные методы, вызываемые аннотированным методом.


:foldable

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

  • :consistent

  • :effect_free

  • :terminates_globally

Утверждение :nothrow в этом списке отсутствует. Компилятор будет пытаться выполнить подстановку констант во время компиляции и регистрировать все возникшие ошибки. Однако имейте в виду, что согласно требованиям утверждения :consistent любой вызов с такой аннотацией должен выдавать одни и те же ошибки при одинаковых значениях аргументов.

Явная аннотация @inbounds внутри функции также отключит свертывание констант и не будет переопределена параметром :foldable.


:total

Это значение setting представляет собой наиболее полный набор побочных эффектов. В настоящее время оно эквивалентно следующим значениям setting:

  • :consistent

  • :effect_free

  • :nothrow

  • :terminates_globally

  • :notaskstate

  • :inaccessiblememonly

:total — это очень строгое утверждение, которое может получить дополнительные значения в будущих версиях Julia (например, если дополнительные побочные эффекты будут добавлены и включены в определение :total). Поэтому его следует применять с осторожностью. По возможности желательно использовать минимальный возможный набор утверждений в отношении побочных эффектов, достаточный для конкретного случая. Если к набору функций применяется множество переопределений побочных эффектов, вместо утверждения :total рекомендуется использовать пользовательский макрос.


Исключение побочных эффектов

Перед именами побочных эффектов можно ставить префикс !. Он означает, что эффект должен быть исключен из ранее определенного метаэффекта. Например, :total !:nothrow означает, что к вызову применяются все утверждения, но он может завершаться ошибкой.


Сравнение с макросом @pure

Макрос @assume_effects :foldable схож с макросом @pure: основное отличие в том, что, как описывалось ранее, требование согласованности (:consistent) применяется на уровне «возраста мира», а не глобально. Однако метод с аннотацией @pure всегда должен соответствовать по крайней мере утверждению :foldable. Еще одно преимущество в том, что побочные эффекты, которые утверждаются с помощью @assume_effects, переносятся на вызывающие объекты межпроцедурно, а чистота, объявляемая с помощью макроса @pure, — нет.

# Base.@deprecateMacro

@deprecate old new [export_old=true]

Выводит из использования метод old, заменяя его вызовом new, определяя в процессе новый метод old с указанной сигнатурой.

Чтобы запретить экспорт метода old, задайте export_old значение false.

Совместимость: Julia 1.5

Начиная с версии Julia 1.5 функции, определенные с помощью макроса @deprecate, не выводят предупреждение при запуске julia без установленного флага --depwarn=yes, так как параметр --depwarn по умолчанию имеет значение no. Предупреждения выводятся при выполнении тестов с помощью Pkg.test().

Примеры

julia> @deprecate old(x) new(x)
old (generic function with 1 method)

julia> @deprecate old(x) new(x) false
old (generic function with 1 method)

Вызовы макроса @deprecate без явных аннотаций типов определят устаревшие методы, принимающие любое количество позиционных и именованных аргументов типа Any.

Совместимость: Julia 1.9

Начиная с версии Julia 1.9 именованные аргументы передаются при отсутствии явной аннотации типа. В более старых версиях позиционные и именованные аргументы можно передавать вручную так: @deprecate old(args...; kwargs...) new(args...; kwargs...).

Чтобы ограничить вывод из использования конкретной сигнатурой, аннотируйте аргументы метода old. Например,

julia> new(x::Int) = x;

julia> new(x::Float64) = 2x;

julia> @deprecate old(x::Int) new(x);

julia> methods(old)
# 1 метод для универсальной функции "old" из Main:
 [1] old(x::Int64)
     @ deprecated.jl:94

определит и выведет из использования метод old(x::Int), который является зеркальным отражением new(x::Int), но не определит и не выведет из использования метод old(x::Float64).

Отсутствующие значения

# Base.MissingType

Missing

Тип без полей, единственный экземпляр которого — missing — используется для представления отсутствующих значений.

См. также описание skipmissing, nonmissingtype, Nothing.

# Base.missingConstant

missing

Единственный экземпляр типа Missing, представляющий отсутствующее значение.

См. также описание NaN, skipmissing, nonmissingtype.

# Base.coalesceFunction

coalesce(x...)

Возвращает первое из значений аргументов, не равное missing, если таковое имеется. В противном случае возвращает missing.

См. также описание функций skipmissing, something и @coalesce.

Примеры

julia> coalesce(missing, 1)
1

julia> coalesce(1, missing)
1

julia> coalesce(nothing, 1)  # возвращает `nothing`

julia> coalesce(missing, missing)
missing

# Base.@coalesceMacro

@coalesce(x...)

Сокращенная версия функции coalesce.

Примеры

julia> f(x) = (println("f($x)"); missing);

julia> a = 1;

julia> a = @coalesce a f(2) f(3) error("`a` is still missing")
1

julia> b = missing;

julia> b = @coalesce b f(2) f(3) error("`b` is still missing")
f(2)
f(3)
ERROR: `b` is still missing
[...]
Совместимость: Julia 1.7

Этот макрос впервые реализован в Julia 1.7.

# Base.ismissingFunction

ismissing(x)

Определяет, имеет ли аргумент x значение missing.

См. также описание skipmissing, isnothing, isnan.

# Base.skipmissingFunction

skipmissing(itr)

Возвращает итератор по элементам аргумента itr, пропуская значения missing. Доступ к элементам возвращенного объекта возможен по индексам объекта itr, если тот поддерживает индексацию. Индексы, соответствующие отсутствующим значениям, недопустимы: они пропускаются функциями keys и eachindex, и при попытке их использования возникает исключение MissingException.

Используйте метод collect для получения массива (Array), содержащего значения, отличные от missing, itr. Обратите внимание: даже если itr — многомерный массив, результат всегда будет иметь тип Vector, так как удалить отсутствующие значения с сохранением измерений входного массива невозможно.

См. также описание функций coalesce, ismissing и something.

Примеры

julia> x = skipmissing([1, missing, 2])
skipmissing(Union{Missing, Int64}[1, missing, 2])

julia> sum(x)
3

julia> x[1]
1

julia> x[2]
ERROR: MissingException: the value at index (2,) is missing
[...]

julia> argmax(x)
3

julia> collect(keys(x))
2-element Vector{Int64}:
 1
 3

julia> collect(skipmissing([1, missing, 2]))
2-element Vector{Int64}:
 1
 2

julia> collect(skipmissing([1 missing; 2 missing]))
2-element Vector{Int64}:
 1
 2

# Base.nonmissingtypeFunction

nonmissingtype(T::Type)

Если T — объединение типов, включающее тип Missing, возвращает новый тип без Missing.

Примеры

julia> nonmissingtype(Union{Int64,Missing})
Int64

julia> nonmissingtype(Any)
Any
Совместимость: Julia 1.3

Эта функция экспортируется начиная с версии Julia 1.3.

Система

# Base.runFunction

run(command, args...; wait::Bool = true)

Выполняет объект команды, заключенный в обратные апострофы (см. раздел, посвященный выполнению внешних программ, в руководстве). Выдает ошибку, если происходят какие-либо неполадки, включая завершение процесса с ненулевым состоянием (когда аргумент wait равен true).

Аргументы args... позволяют передать в команду дескрипторы файлов в таком же порядке, как и стандартные дескрипторы файлов Unix (например, stdin, stdout, stderr, FD(3), FD(4)...).

Если аргумент wait равен false, процесс выполняется асинхронно. Вы можете дождаться его завершения и проверить его состояние выхода, вызвав success для возвращенного объекта процесса.

Когда аргумент wait имеет значение false, потоки ввода-вывода процесса направляются в devnull. Когда аргумент wait имеет значение true, потоки ввода-вывода являются общими с родительским процессом. Для управления перенаправлением ввода-вывода используйте метод pipeline.

# Base.devnullConstant

devnull

Используется при перенаправлении потоков: все записываемые в devnull данные удаляются. Эквивалентно /dev/null в Unix или NUL в Windows. Использование:

run(pipeline(`cat test.txt`, devnull))

# Base.successFunction

success(command)

Выполняет объект команды, заключенный в обратные апострофы (см. раздел, посвященный выполнению внешних программ, в руководстве), и сообщает, завершилось ли выполнение успешно (выход с кодом 0). Если запустить процесс не удается, возникает исключение.

# Base.process_runningFunction

process_running(p::Process)

Определяет, выполняется ли процесс в данный момент.

# Base.process_exitedFunction

process_exited(p::Process)

Определяет, завершился ли процесс.

# Base.killMethod

kill(p::Process, signum=Base.SIGTERM)

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

# Base.Sys.set_process_titleFunction

Sys.set_process_title(title::AbstractString)

Задает заголовок процесса. В некоторых операционных системах это холостая операция.

# Base.Sys.get_process_titleFunction

Sys.get_process_title()

Возвращает заголовок процесса. В некоторых системах всегда возвращает пустую строку.

# Base.ignorestatusFunction

ignorestatus(command)

Помечает объект команды так, что если его выполнение завершается с отличным от нуля кодом результата, ошибка не возникает.

# Base.detachFunction

detach(command)

Помечает объект команды так, что он выполняется в новой группе процессов, благодаря чему он может продолжать существовать после завершения процесса Julia и в него не передаются прерывания CTRL+C.

# Base.CmdType

Cmd(cmd::Cmd; ignorestatus, detach, windows_verbatim, windows_hide, env, dir)

Создает объект Cmd, представляющий внешнюю программу и ее аргументы, из cmd с заданием значений необязательных именованных аргументов:

  • ignorestatus::Bool: если задано значение true (по умолчанию false), объект Cmd не будет выдавать ошибку в случае ненулевого кода возврата.

  • detach::Bool: если задано значение true (по умолчанию false), объект Cmd будет выполняться в новой группе процессов, благодаря чему он сможет продолжать существовать после завершения процесса julia и в него не будут передаваться прерывания CTRL+C.

  • windows_verbatim::Bool: если задано значение true (по умолчанию false), то в Windows объект Cmd отправит в процесс командную строку, не заключая аргументы в кавычки и не экранируя их, даже если аргументы содержат пробелы. (В Windows аргументы передаются в программу в виде единой командной строки, и за анализ аргументов отвечает сама программа. По умолчанию пустые аргументы и аргументы с пробелами или символами табуляции в командной строке заключаются в двойные кавычки (“), а перед символами иставятся обратные слэши. Аргументwindows_verbatim=true полезен для запуска программ, которые анализируют командную строку нестандартным способом.) Действует только в операционной системе Windows.

  • windows_hide::Bool: если задано значение true (по умолчанию false), то в Windows новое окно консоли не отображается при выполнении объекта Cmd. Не действует, если консоль уже открыта, или в системах, отличных от Windows.

  • env: задает переменные среды, используемые при выполнении объекта Cmd. env — это объект типа словарь со строковыми ключами и значениями, либо массив строк в форме "var=val", либо массив или кортеж пар "var"=>val. Чтобы изменить (а не заменить) существующую среду, инициализируйте env с помощью copy(ENV), а затем задайте env["var"]=val нужным образом. Чтобы добавить в среду объекта Cmd новый блок, не заменяя все элементы, используйте функцию addenv(). Она возвращает объект Cmd с обновленной средой.

  • dir::AbstractString: указывает рабочий каталог для команды (вместо текущего каталога).

Если какие-либо именованные аргументы не указаны, используются текущие значения из cmd. Обычно для создания объекта Cmd используются обратные апострофы, например:

Cmd(`echo "Hello world"`, ignorestatus=true, detach=false)

# Base.setenvFunction

setenv(command::Cmd, env; dir)

Задает переменные среды, используемые при выполнении указанной команды command. env — это объект типа словарь со строковыми ключами и значениями, либо массив строк в форме "var=val", либо ноль или несколько аргументов в виде пар "var"=>val. Чтобы изменить (а не заменить) существующую среду, создайте env с помощью copy(ENV), а затем задайте env["var"]=val нужным образом, или используйте функцию addenv.

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

См. также Cmd, addenv, ENV, pwd.

# Base.addenvFunction

addenv(command::Cmd, env...; inherit::Bool = true)

Объединяет новые переменные среды со средой указанного объекта Cmd, возвращая новый объект Cmd. Если ключи повторяются, соответствующие переменные заменяются. Если в объекте, переданном в аргументе command, значения переменных среды еще не заданы, при вызове функции addenv() наследуется текущая среда при условии, что аргумент inherit имеет значение true. Ключи со значением nothing удаляются из env.

См. также описание функций Cmd, setenv и ENV.

Совместимость: Julia 1.6

Для этой функции требуется версия не ниже Julia 1.6.

# Base.withenvFunction

withenv(f, kv::Pair...)

Выполняет функцию f в среде, которая временно изменена (а не заменена, как при использовании setenv) с помощью одного или нескольких аргументов kv в виде пар "var"=>val. Функция withenv обычно применяется с синтаксисом withenv(kv...) do ... end. С помощью значения nothing можно временно отключить переменную среды (если она задана). Когда функция withenv возвращает управление, восстанавливается исходная среда.

Изменение среды не является потокобезопасной операцией. Для выполнения внешних команд с другой средой из родительского процесса лучше использовать addenv, а не withenv.

# Base.setcpuaffinityFunction

setcpuaffinity(original_command::Cmd, cpus) -> command::Cmd

Задает привязку к ЦП для команды command в виде списка идентификаторов ЦП cpus (с отсчетом от 1). Передача значения cpus = nothing отменяет привязку к ЦП, если она была настроена для команды original_command.

Эта функция поддерживается только в Linux и Windows. В macOS она не поддерживается, так как библиотека libuv не поддерживает настройку привязки.

Совместимость: Julia 1.8

Для этой функции требуется версия Julia не ниже 1.8.

Примеры

В Linux увидеть, как работает функция setcpuaffinity, можно с помощью программы командной строки taskset.

julia> run(setcpuaffinity(`sh -c 'taskset -p $$'`, [1, 2, 5]));
pid 2273's current affinity mask: 13

Обратите внимание: значение маски 13 означает, что включены первый, второй и пятый биты (если считать от младшего разряда):

julia> 0b010011
0x13

# Base.pipelineMethod

pipeline(from, to, ...)

Создает конвейер из источника данных в конечный объект. Источником и конечным объектом могут быть команды, потоки ввода-вывода, строки или результаты других вызовов метода pipeline. По крайней мере один аргумент должен быть командой. Строки — это имена файлов. Если аргументов больше двух, они сцепляются слева направо. Например, вызов pipeline(a,b,c) эквивалентен pipeline(pipeline(a,b),c). Это позволяет определять многоступенчатые конвейеры более кратко.

Примеры:

run(pipeline(`ls`, `grep xyz`))
run(pipeline(`ls`, "out.txt"))
run(pipeline("out.txt", `grep xyz`))

# Base.pipelineMethod

pipeline(command; stdin, stdout, stderr, append=false)

Перенаправляет ввод-вывод в указанную команду command или из нее. Именованные аргументы определяют потоки команды, которые должны перенаправляться. Аргумент append определяет то, добавляются ли выходные данные PNG. Это более общая версия функции pipeline с двумя аргументами. Вызов pipeline(from, to) эквивалентен вызову pipeline(from, stdout=to), когда from — это команда, или вызову pipeline(to, stdin=from), когда from — это источник данных другого типа.

Примеры:

run(pipeline(`dothings`, stdout="out.txt", stderr="errs.txt"))
run(pipeline(`update`, stdout="log.txt", append=true))

# Base.Libc.gethostnameFunction

gethostname() -> AbstractString

Возвращает имя хоста локального компьютера.

# Base.Libc.getpidMethod

getpid() -> Int32

Возвращает идентификатор процесса Julia.

# Base.Libc.getpidMethod

getpid(process) -> Int32

Возвращает идентификатор дочернего процесса, если он все еще существует.

Совместимость: Julia 1.1

Для этой функции требуется версия Julia не ниже 1.1.

# Base.Libc.timeMethod

time()

Возвращает системное время в секундах с начала отсчета Unix-времени с достаточно высокой точностью (обычно на уровне микросекунд).

# Base.time_nsFunction

time_ns() -> UInt64

Возвращает время в наносекундах. Время, соответствующее значению 0, не определено. Отсчет времени начинается заново каждые 5,8 года.

# Base.@timeMacro

@time expr
@time "description" expr

Макрос, который выполняет выражение и выводит время, затраченное на выполнение, количество объектов, размещенных в памяти, и общее количество байтов, выделенных в ходе выполнения, после чего возвращает значение выражения. Время, затраченное на сборку мусора, компиляцию нового кода или перекомпиляцию недействительного кода, отображается в процентах.

При необходимости можно указать строку с описанием, которая будет выводиться перед отчетом о затраченном времени.

Система может проверять содержимое выражения @time и компилировать вызываемый код, прежде чем начинать выполнение выражения верхнего уровня. В этом случае часть времени, затраченного на компиляцию, не учитывается. Чтобы учесть это время, можно выполнить @time @eval ....

См. также описание @showtime, @timev, @timed, @elapsed, @allocated и @allocations.

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

Совместимость: Julia 1.8

Возможность добавления описания появилась в версии Julia 1.8.

Recompilation time being shown separately from compilation time was introduced in Julia 1.8
julia> x = rand(10,10);

julia> @time x * x;
  0.606588 seconds (2.19 M allocations: 116.555 MiB, 3.75% gc time, 99.94% compilation time)

julia> @time x * x;
  0.000009 seconds (1 allocation: 896 bytes)

julia> @time begin
           sleep(0.3)
           1+1
       end
  0.301395 seconds (8 allocations: 336 bytes)
2

julia> @time "A one second sleep" sleep(1)
A one second sleep: 1.005750 seconds (5 allocations: 144 bytes)

julia> for loop in 1:3
            @time loop sleep(1)
        end
1: 1.006760 seconds (5 allocations: 144 bytes)
2: 1.001263 seconds (5 allocations: 144 bytes)
3: 1.003676 seconds (5 allocations: 144 bytes)

# Base.@showtimeMacro

@showtime expr

Действует так же, как макрос @time, но также для справки выводит анализируемое выражение.

Совместимость: Julia 1.8

Этот макрос был добавлен в версии Julia 1.8.

См. также описание @time.

julia> @showtime sleep(1)
sleep(1): 1.002164 seconds (4 allocations: 128 bytes)

# Base.@timevMacro

@timev expr
@timev "description" expr

Это подробная версия макроса @time. Сначала она выводит ту же информацию, что и @time, затем все ненулевые счетчики выделения памяти, а затем возвращает значение Julia.

При необходимости можно указать строку с описанием, которая будет выводиться перед отчетом о затраченном времени.

Совместимость: Julia 1.8

Возможность добавления описания появилась в версии Julia 1.8.

См. также описание функций @time, @timed, @elapsed и @allocated и @allocations.

julia> x = rand(10,10);

julia> @timev x * x;
  0.546770 seconds (2.20 M allocations: 116.632 MiB, 4.23% gc time, 99.94% compilation time)
elapsed time (ns): 546769547
gc time (ns):      23115606
bytes allocated:   122297811
pool allocs:       2197930
non-pool GC allocs:1327
malloc() calls:    36
realloc() calls:   5
GC pauses:         3

julia> @timev x * x;
  0.000010 seconds (1 allocation: 896 bytes)
elapsed time (ns): 9848
bytes allocated:   896
pool allocs:       1

# Base.@timedMacro

@timed

Макрос, который выполняет выражение и возвращает его значение, затраченное время, общий объем выделенной памяти в байтах, длительность сборки мусора и объект с различными счетчиками выделения памяти.

Система может проверять содержимое выражения @timed и компилировать вызываемый код, прежде чем начинать выполнение выражения верхнего уровня. В этом случае часть времени, затраченного на компиляцию, не учитывается. Чтобы учесть это время, можно выполнить @timed @eval ....

См. также описание функций @time, @timev, @elapsed и @allocated и @allocations.

julia> stats = @timed rand(10^6);

julia> stats.time
0.006634834

julia> stats.bytes
8000256

julia> stats.gctime
0.0055765

julia> propertynames(stats.gcstats)
(:allocd, :malloc, :realloc, :poolalloc, :bigalloc, :freecall, :total_time, :pause, :full_sweep)

julia> stats.gcstats.total_time
5576500
Совместимость: Julia 1.5

В Julia 1.5 тип возвращаемого этим макросом значения изменился с Tuple на NamedTuple.

# Base.@elapsedMacro

@elapsed

Макрос, который вычисляет выражение, но вместо результата возвращает количество секунд, затраченное на выполнение, в виде числа с плавающей запятой.

Система может проверять содержимое выражения @elapsed и компилировать вызываемый код, прежде чем начинать выполнение выражения верхнего уровня. В этом случае часть времени, затраченного на компиляцию, не учитывается. Чтобы учесть это время, можно выполнить @elapsed @eval ....

См. также описание функций @time, @timev, @timed и @allocated и @allocations.

julia> @elapsed sleep(0.3)
0.301391426

# Base.@allocatedMacro

@allocated

Макрос, который вычисляет выражение, но вместо результата возвращает общий объем памяти в байтах, выделенный в ходе вычисления.

См. также описание @allocations, @time, @timev, @timed, и @elapsed.

julia> @allocated rand(10^6)
8000080

# Base.@allocationsMacro

@allocations

Макрос, который вычисляет выражение, но вместо результата возвращает общее количество выделений в ходе вычисления.

См. также описание @allocated, @time, @timev, @timed, и @elapsed.

julia> @allocations rand(10^6)
2
Совместимость: Julia 1.9

Этот макрос был добавлен в версии Julia 1.9.

# Base.EnvDictType

EnvDict() -> EnvDict

Единственный экземпляр этого типа предоставляет интерфейс в виде хэш-таблицы для доступа к переменным среды.

# Base.ENVConstant

ENV

Ссылка на тип EnvDict с единственным экземпляром, который предоставляет интерфейс в виде словаря для доступа к системным переменным среды.

(В Windows в системных переменных среды регистр символов не учитывается, поэтому ENV преобразовывает все ключи в верхний регистр для отображения, итерации и копирования. В переносимом коде переменные не должны различаться по регистру символов; следует учитывать, что, несмотря на написание имени переменной строчными буквами, соответствующий ключ в ENV может иметь написание прописными.)

Изменение среды не является потокобезопасной операцией.

Примеры

julia> ENV
Base.EnvDict with "50" entries:
  "SECURITYSESSIONID"            => "123"
  "USER"                         => "username"
  "MallocNanoZone"               => "0"
  ⋮                              => ⋮

julia> ENV["JULIA_EDITOR"] = "vim"
"vim"

julia> ENV["JULIA_EDITOR"]
"vim"

См. также описание withenv, addenv.

# Base.Sys.STDLIBConstant

Sys.STDLIB::String

Строка, которая содержит полный путь к каталогу, где содержатся пакеты stdlib.

# Base.Sys.isunixFunction

Sys.isunix([os])

Предикат для проверки того, предоставляет ли ОС Unix-подобный интерфейс. См. раздел документации Обработка операционной системы.

# Base.Sys.isappleFunction

Sys.isapple([os])

Предикат для проверки того, является ли ОС производной от Apple Macintosh OS X или Darwin. См. раздел документации Обработка операционной системы.

# Base.Sys.islinuxFunction

Sys.islinux([os])

Предикат для проверки того, является ли ОС производной от Linux. См. раздел документации Обработка операционной системы.

# Base.Sys.isbsdFunction

Sys.isbsd([os])

Предикат для проверки того, является ли ОС производной от BSD. См. раздел документации Обработка операционной системы.

Ядро Darwin происходит от BSD, поэтому функция Sys.isbsd() возвращает значение true в системах macOS. Чтобы исключить macOS, используйте вызов Sys.isbsd() && !Sys.isapple().

# Base.Sys.isfreebsdFunction

Sys.isfreebsd([os])

Предикат для проверки того, является ли ОС производной от FreeBSD. См. раздел документации Обработка операционной системы.

Не следует путать с функцией Sys.isbsd(), которая возвращает значение true как во FreeBSD, так и в других системах на основе BSD. Sys.isfreebsd() применяется только к FreeBSD.

Совместимость: Julia 1.1

Для этой функции требуется версия Julia не ниже 1.1.

# Base.Sys.isopenbsdFunction

Sys.isopenbsd([os])

Предикат для проверки того, является ли ОС производной от OpenBSD. См. раздел документации Обработка операционной системы.

Не следует путать с функцией Sys.isbsd(), которая возвращает значение true как в OpenBSD, так и в других системах на основе BSD. Sys.isopenbsd() применяется только к OpenBSD.

Совместимость: Julia 1.1

Для этой функции требуется версия Julia не ниже 1.1.

# Base.Sys.isnetbsdFunction

Sys.isnetbsd([os])

Предикат для проверки того, является ли ОС производной от NetBSD. См. раздел документации Обработка операционной системы.

Не следует путать с функцией Sys.isbsd(), которая возвращает значение true как в NetBSD, так и в других системах на основе BSD. Sys.isnetbsd() применяется только к NetBSD.

Совместимость: Julia 1.1

Для этой функции требуется версия Julia не ниже 1.1.

# Base.Sys.isdragonflyFunction

Sys.isdragonfly([os])

Предикат для проверки того, является ли ОС производной от DragonFly BSD. См. раздел документации Обработка операционной системы.

Не следует путать с функцией Sys.isbsd(), которая возвращает значение true как в DragonFly, так и в других системах на основе BSD. Sys.isdragonfly() применяется только к DragonFly.

Совместимость: Julia 1.1

Для этой функции требуется версия Julia не ниже 1.1.

# Base.Sys.iswindowsFunction

Sys.iswindows([os])

Предикат для проверки того, является ли ОС производной от Microsoft Windows NT. См. раздел документации Обработка операционной системы.

# Base.Sys.windows_versionFunction

Sys.windows_version()

Возвращает номер версии ядра Windows NT в виде значения типа VersionNumber, то есть v"major.minor.build" или, если функция выполняется не в Windows, v"0.0.0".

# Base.Sys.free_memoryFunction

Sys.free_memory()

Возвращает общий объем свободной оперативной памяти в байтах.

# Base.Sys.total_memoryFunction

Sys.total_memory()

Возвращает общий объем оперативной памяти (в том числе занятой в настоящее время) в байтах. Этот объем может ограничиваться, например контрольными группами Linux. Чтобы получить объем без ограничений, воспользуйтесь функцией Sys.physical_memory().

# Base.Sys.free_physical_memoryFunction

Sys.free_physical_memory()

Возвращает объем свободной памяти системы в байтах. Текущему процессу может быть доступен не весь объем; для получения фактического объема доступной памяти используйте функцию Sys.free_memory().

# Base.Sys.total_physical_memoryFunction

Sys.total_physical_memory()

Возвращает общий объем оперативной памяти (в том числе занятой в настоящее время) в байтах. Текущему процессу может быть доступен не весь объем; см. описание функции Sys.total_memory().

# Base.Sys.uptimeFunction

Sys.uptime()

Возвращает текущее время бесперебойной работы системы в секундах.

# Base.Sys.isjsvmFunction

Sys.isjsvm([os])

Предикат для проверки того, запущена ли среда Julia на виртуальной машине JavaScript (JSVM), включая, например, встраивание WebAssembly JavaScript в веб-браузер.

Совместимость: Julia 1.2

Для этой функции требуется версия Julia не ниже 1.2.

# Base.Sys.loadavgFunction

Sys.loadavg()

Возвращает среднее значение нагрузки. См. https://en.wikipedia.org/wiki/Load_(computing).

# Base.Sys.isexecutableFunction

Sys.isexecutable(path::String)

Возвращает true, если заданный path имеет разрешения исполняемого файла.

До версии Julia 1.6 эта функция некорректно опрашивала списки ACL файловой системы в Windows и поэтому возвращала true для любого файла. Начиная с версии Julia 1.6 она правильно определяет, помечен ли файл как исполняемый.

# Base.@staticMacro

@static

Частично вычисляет выражение во время анализа.

Например, @static Sys.iswindows() ? foo : bar вычисляет функцию Sys.iswindows() и вставляет foo или bar в выражение. Это полезно в случаях, когда конструкция недействительна на других платформах, например при вызове ccall несуществующей функции. Допустимы и такие варианты синтаксиса: @static if Sys.isapple() foo end и @static foo <&&,||> bar.

Управление версиями

# Base.VersionNumberType

VersionNumber

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

Объекты VersionNumber можно сравнивать с помощью любых стандартных операторов сравнения (==, <, <= и т. д.) согласно правилам semver.

См. также описание макроса @v_str, который позволяет эффективно создавать объекты VersionNumber на основе литеральных строк в формате semver, описание константы VERSION, содержащей значение VersionNumber используемой версии Julia, а также раздел, посвященный числовым литералам версии в руководстве.

Примеры

julia> a = VersionNumber(1, 2, 3)
v"1.2.3"

julia> a >= v"1.2"
true

julia> b = VersionNumber("2.0.1-rc1")
v"2.0.1-rc1"

julia> b >= v"2.0.1"
false

# Base.@v_strMacro

@v_str

Строковый макрос, который служит для анализа строки и ее преобразования в VersionNumber.

Примеры

julia> v"1.2.3"
v"1.2.3"

julia> v"2.0.1-rc1"
v"2.0.1-rc1"

Ошибки

# Base.errorFunction

error(message::AbstractString)

Вызывает исключение ErrorException с указанным сообщением.

error(msg...)

Вызывает исключение ErrorException с указанным сообщением.

# Core.throwFunction

throw(e)

Вызывает объект исключения.

См. также описание rethrow, error.

# Base.rethrowFunction

rethrow()

Повторно вызывает текущее исключение из блока catch. Повторно вызванное исключение будет передаваться далее, как если бы оно не было перехвачено.

Альтернативная форма rethrow(e) позволяет связать другой объект исключения e с текущей обратной трассировкой. Однако это дает неверное представление о состоянии программы в момент возникновения ошибки, поэтому рекомендуется вместо этого вызвать новое исключение с помощью throw(e). В Julia 1.1 и более поздних версиях при использовании вызова throw(e) первоначальное исключение сохраняется в стеке; см. описание функции current_exceptions.

# Base.backtraceFunction

backtrace()

Возвращает объект обратной трассировки для текущей точки программы.

# Base.catch_backtraceFunction

catch_backtrace()

Возвращает обратную трассировку текущего исключения для использования в блоках catch.

# Base.current_exceptionsFunction

current_exceptions(task::Task=current_task(); [backtrace::Bool=true])

Возвращает стек исключений, обрабатываемых в настоящее время. В случае с вложенными блоками catch текущих исключений может быть несколько. Последним в стеке при этом будет последнее вызванное исключение. Стек возвращается в виде объекта ExceptionStack — абстрактного вектора (AbstractVector) именованных кортежей (exception,backtrace). Если аргумент backtrace равен false, обратная трассировка в каждой паре будет равна nothing.

При передаче аргумента task явным образом возвращается стек текущих исключений для произвольной задачи. Это полезно для проверки задач, которые не удалось выполнить из-за неперехваченных исключений.

Совместимость: Julia 1.7

В версиях Julia 1.1—​1.6 эта функция была экспериментальной, называлась catch_stack() и возвращала простой вектор кортежей.

# Base.@assertMacro

@assert cond [text]

Вызывает ошибку AssertionError, если условие cond равно false. Предпочтительный синтаксис для написания утверждений. Если утверждение не соблюдается, может выводиться необязательное сообщение text.

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

Примеры

julia> @assert iseven(3) "3 is an odd number!"
ERROR: AssertionError: 3 is an odd number!

julia> @assert isodd(3) "What even are numbers?"

# Base.Experimental.register_error_hintFunction

Experimental.register_error_hint(handler, exceptiontype)

Регистрирует функцию-подсказку handler(io, exception), которая может предлагать пользователям возможные способы обхода ошибок. Функция handler должна проверить, соответствует ли исключение exception условиям для выдачи подсказки, и, если да, направить выходные данные в io. В пакетах функция register_error_hint должна вызываться из функции __init__.

Для определенных типов исключений функция handler должна принимать дополнительные аргументы.

  • MethodError: укажите handler(io, exc::MethodError, argtypes, kwargs), чтобы разделить аргументы на позиционные и именованные.

Текст подсказки обычно должен начинаться с \n.

При определении пользовательских типов исключений метод showerror может поддерживать подсказки путем вызова Experimental.show_error_hints.

Пример

julia> module Hinter

       only_int(x::Int)      = 1
       any_number(x::Number) = 2

       function __init__()
           Base.Experimental.register_error_hint(MethodError) do io, exc, argtypes, kwargs
               if exc.f == only_int
                    # Цвет необязателен, просто демонстрируется такая возможность.
                    print(io, "\nDid you mean to call ")
                    printstyled(io, "`any_number`?", color=:cyan)
               end
           end
       end

       end

Если теперь вызвать Hinter.only_int для какого-либо объекта не типа Int (что приведет к ошибке MethodError), будет выведена подсказка:

julia> Hinter.only_int(1.0)
ERROR: MethodError: no method matching only_int(::Float64)
Did you mean to call `any_number`?
Closest candidates are:
    ...
Совместимость: Julia 1.5

Подсказки для пользовательских ошибок доступны начиная с версии Julia 1.5.

Это экспериментальный интерфейс. Он может быть изменен или удален без уведомления. Чтобы застраховаться на случай изменений, желательно размещать все регистрации внутри блока if isdefined(Base.Experimental, :register_error_hint) ... end.

# Base.Experimental.show_error_hintsFunction

Experimental.show_error_hints(io, ex, args...)

Вызывает все обработчики из Experimental.register_error_hint для определенного типа исключения typeof(ex). В args должны содержаться все остальные аргументы, которые ожидает обработчик для этого типа.

Совместимость: Julia 1.5

Подсказки для пользовательских ошибок доступны начиная с версии Julia 1.5.

Это экспериментальный интерфейс. Он может быть изменен или удален без уведомления.

# Core.ArgumentErrorType

ArgumentError(msg)

В функцию переданы недопустимые аргументы. msg — сообщение с описанием ошибки.

# Core.AssertionErrorType

AssertionError([msg])

Условие утверждения не равно true. Необязательный аргумент msg — это строка с описанием ошибки.

Примеры

julia> @assert false "this is not true"
ERROR: AssertionError: this is not true

Ошибка AssertionError обычно вызывается макросом @assert.

# Core.BoundsErrorType

BoundsError([a],[i])

При обращении к массиву a по индексу была произведена попытка получить доступ к выходящему за границы элементу по индексу i.

Примеры

julia> A = fill(1.0, 7);

julia> A[8]
ERROR: BoundsError: attempt to access 7-element Vector{Float64} at index [8]


julia> B = fill(1.0, (2,3));

julia> B[2, 4]
ERROR: BoundsError: attempt to access 2×3 Matrix{Float64} at index [2, 4]


julia> B[9]
ERROR: BoundsError: attempt to access 2×3 Matrix{Float64} at index [9]

# Base.CompositeExceptionType

CompositeException

Оболочка для вектора (Vector) исключений, вызванных объектом Task (например, созданных удаленным рабочим процессом, подключенным через канал, локальной асинхронной операцией записи или удаленным рабочим процессом под управлением pmap). Содержит информацию о серии исключений. Например, если группа рабочих процессов выполняет ряд задач и происходит сбой нескольких из этих процессов, объект CompositeException будет содержать «пакет» информации о том, где и почему произошли исключения, от каждого рабочего процесса.

# Base.DimensionMismatchType

DimensionMismatch([msg])

Вызываемые объекты имеют другую размерность. Необязательный аргумент msg — это строка с описанием ошибки.

# Core.DivideErrorType

DivideError()

Предпринята попытка целочисленного деления с нулем в знаменателе.

Примеры

julia> 2/0
Inf

julia> div(2, 0)
ERROR: DivideError: integer division error
Stacktrace:
[...]

# Core.DomainErrorType

DomainError(val)
DomainError(val, msg)

Аргумент val функции или конструктора не входит в область определения.

Примеры

julia> sqrt(-1)
ERROR: DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
Stacktrace:
[...]

# Base.EOFErrorType

EOFError()

Больше нет доступных данных для чтения из файла или потока.

# Core.ErrorExceptionType

ErrorException(msg)

Универсальный тип ошибки. Сообщение об ошибке в поле .msg может содержать уточняющую информацию.

Примеры

julia> ex = ErrorException("I've done a bad thing");

julia> ex.msg
"I've done a bad thing"

# Core.InexactErrorType

InexactError(name::Symbol, T, val)

Невозможно точно преобразовать значение val в тип T в методе функции name.

Примеры

julia> convert(Float64, 1+2im)
ERROR: InexactError: Float64(1 + 2im)
Stacktrace:
[...]

# Core.InterruptExceptionType

InterruptException()

Процесс был остановлен в результате прерывания от терминала (CTRL+C).

Обратите внимание, что в скрипте Julia, запущенном без параметра -i (интерактивный сеанс), исключение InterruptException по умолчанию не вызывается. Чтобы восстановить поведение REPL, можно вызвать Base.exit_on_sigint(false) в скрипте. Скрипт Julia можно также запустить с помощью команды

julia -e "include(popfirst!(ARGS))" script.jl

чтобы прерывание CTRL+C во время выполнения вызывало исключение InterruptException.

# Base.KeyErrorType

KeyError(key)

При обращении к объекту типа AbstractDict (Dict) или Set по индексу была произведена попытка получить доступ к несуществующему элементу или удалить его.

# Core.LoadErrorType

LoadError(file::AbstractString, line::Int, error)

При попытке применить функцию include, require или using к файлу произошла ошибка. Подробные сведения об ошибке должны быть доступны в поле .error.

Совместимость: Julia 1.7

Начиная с версии Julia 1.7 макросы @macroexpand, @macroexpand1 и macroexpand больше не выдают ошибки LoadError.

# Core.MethodErrorType

MethodError(f, args)

В заданной универсальной функции нет метода с требуемой сигнатурой типов. Либо же нет уникального наиболее специфичного метода.

# Base.MissingExceptionType

MissingException(msg)

Это исключение вызывается, если значение missing встречается в ситуации, в которой оно не поддерживается. Сообщение об ошибке в поле msg может содержать уточняющую информацию.

# Core.OutOfMemoryErrorType

OutOfMemoryError()

Операция выделила слишком много памяти для обработки системой или сборщиком мусора.

# Core.ReadOnlyMemoryErrorType

ReadOnlyMemoryError()

Операция попыталась выполнить запись в память, доступную только для чтения.

# Core.OverflowErrorType

OverflowError(msg)

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

# Base.ProcessFailedExceptionType

ProcessFailedException

Указывает на статус выхода процесса, свидетельствующий о проблеме. При выполнении команд или конвейеров это исключение указывает на возврат ненулевого кода выхода (то есть вызванный процесс завершился сбоем).

# Base.TaskFailedExceptionType

TaskFailedException

Это исключение возникает при вызове wait(t), когда задача t завершается сбоем. TaskFailedException заключает в оболочку завершившуюся сбоем задачу t.

# Core.StackOverflowErrorType

StackOverflowError()

Размер вызова функции превысил размер стека вызовов. Обычно причина заключается в бесконечной рекурсии вызова.

# Base.SystemErrorType

SystemError(prefix::AbstractString, [errno::Int32])

Системный вызов завершился с кодом ошибки (в глобальной переменной errno).

# Core.TypeErrorType

TypeError(func::Symbol, context::AbstractString, expected::Type, got)

Сбой утверждения типа или вызов встроенной функции с неверным типом аргумента.

# Core.UndefKeywordErrorType

UndefKeywordError(var::Symbol)

В вызове функции не задан обязательный именованный аргумент var.

Примеры

julia> function my_func(;my_arg)
           return my_arg + 1
       end
my_func (generic function with 1 method)

julia> my_func()
ERROR: UndefKeywordError: keyword argument `my_arg` not assigned
Stacktrace:
 [1] my_func() at ./REPL[1]:2
 [2] top-level scope at REPL[2]:1

# Core.UndefRefErrorType

UndefRefError()

Элемент или поле не определены для указанного объекта.

Примеры

julia> struct MyType
           a::Vector{Int}
           MyType() = new()
       end

julia> A = MyType()
MyType(#undef)

julia> A.a
ERROR: UndefRefError: access to undefined reference
Stacktrace:
[...]

# Core.UndefVarErrorType

UndefVarError(var::Symbol)

Символ не определен в текущей области.

Примеры

julia> a
ERROR: UndefVarError: `a` not defined

julia> a = 1;

julia> a
1

# Base.StringIndexErrorType

StringIndexError(str, i)

Произошла ошибка из-за попытки доступа к строке str по недопустимому индексу i.

# Core.InitErrorType

InitError(mod::Symbol, error)

При выполнении функции __init__ модуля произошла ошибка. Вызванная ошибка доступна в поле .error.

# Base.retryFunction

retry(f;  delays=ExponentialBackOff(), check=nothing) -> Function

Возвращает анонимную функцию, которая вызывает функцию f. Если происходит исключение, функция f вызывается повторно каждый раз, когда check возвращает значение true, после паузы, длительность которой указана в секундах в аргументе delays. В check должно передаваться текущее состояние delays и объект Exception.

Совместимость: Julia 1.2

До версии Julia 1.2 эта функция имела ограниченную сигнатуру f::Function.

Примеры

retry(f, delays=fill(5.0, 3))
retry(f, delays=rand(5:10, 2))
retry(f, delays=Base.ExponentialBackOff(n=3, first_delay=5, max_delay=1000))
retry(http_get, check=(s,e)->e.status == "503")(url)
retry(read, check=(s,e)->isa(e, IOError))(io, 128; all=false)

# Base.ExponentialBackOffType

ExponentialBackOff(; n=1, first_delay=0.05, max_delay=10.0, factor=5.0, jitter=0.1)

Итератор типа Float64 длиной n, элементы которого увеличиваются в геометрической прогрессии со скоростью в интервале factor * (1 ± jitter). Первый элемент — first_delay; максимальный размер элементов — max_delay.

События

# Base.TimerMethod

Timer(callback::Function, delay; interval = 0)

Создает таймер, при каждом срабатывании которого выполняется функция callback.

Ожидающие задачи активируются, и функция callback сначала вызывается после задержки, равной delay секунд, а затем вызывается повторно с интервалом в interval секунд. Если аргумент interval равен 0, обратный вызов выполняется только один раз. Функция callback вызывается с одним аргументом — самим таймером. Чтобы остановить таймер, вызовите функцию close. Если отсчет таймера завершился, функция cb может быть выполнена еще один последний раз.

Примеры

В этом случае первое число выводится после паузы в две секунды, а следующие числа — с небольшой задержкой.

julia> begin
           i = 0
           cb(timer) = (global i += 1; println(i))
           t = Timer(cb, 2, interval=0.2)
           wait(t)
           sleep(0.5)
           close(t)
       end
1
2
3

# Base.TimerType

Timer(delay; interval = 0)

Создает таймер, который активирует задачи, ожидающие его срабатывания (вызывая функцию wait для объекта таймера).

Ожидающие задачи активируются после первоначальной задержки, равной не менее delay секунд, а затем выполняются повторно с интервалом не менее interval секунд. Если аргумент interval равен 0, таймер срабатывает только один раз. Когда таймер закрывается (с помощью функции close), ожидающие задачи активируются с ошибкой. Для проверки того, активен ли все еще таймер, используйте функцию isopen.

Интервал interval может постепенно сдвигаться из-за накопления задержек. Если нужно, чтобы события происходили в определенные абсолютные моменты времени, создавайте новый таймер после завершения отсчета предыдущего, вычисляя разницу до следующего момента времени.

Для обновления состояния объекта Timer требуются точки выхода. Например, isopen(t::Timer) нельзя использовать для завершения бесконечного цикла while по тайм-ауту.

# Base.AsyncConditionType

AsyncCondition()

Создает асинхронное условие, которое активирует задачи, ожидающие его срабатывания (вызывая функцию wait для объекта), при получении сообщения из C посредством вызова uv_async_send. Когда объект закрывается (с помощью функции close), ожидающие задачи активируются с ошибкой. Для проверки того, активен ли все еще объект, используйте функцию isopen.

Это дает возможность неявного упорядочения памяти при получении и освобождении между отправляющими и ожидающими потоками.

# Base.AsyncConditionMethod

AsyncCondition(callback::Function)

Создает асинхронное условие, которое вызывает указанную функцию callback. Функции callback передается один аргумент — сам объект асинхронного условия.

Отображение

# Base.nameofMethod

nameof(m::Module) -> Symbol

Возвращает имя модуля Module в виде значения типа Symbol.

Примеры

julia> nameof(Base.Broadcast)
:Broadcast

# Base.parentmoduleFunction

parentmodule(m::Module) -> Module

Возвращает модуль Module, содержащий данный модуль. Собственным родительским модулем является Main.

См. также описание names, nameof, fullname, @__MODULE__.

Примеры

julia> parentmodule(Main)
Main

julia> parentmodule(Base.Broadcast)
Base
parentmodule(t::DataType) -> Module

Определяет модуль, в котором содержится определение типа DataType (возможно, инкапсулированного в UnionAll).

Примеры

julia> module Foo
           struct Int end
       end
Foo

julia> parentmodule(Int)
Core

julia> parentmodule(Foo.Int)
Foo
parentmodule(f::Function) -> Module

Определяет модуль, в котором содержится (первое) определение универсальной функции.

parentmodule(f::Function, types) -> Module

Определяет модуль, в котором содержится указанное определение универсальной функции.

# Base.pathofMethod

pathof(m::Module)

Возвращает путь к файлу m.jl, из которого был импортирован (import) модуль m, или значение nothing, если модуль m не был импортирован из пакета.

Используйте функцию dirname для получения имени каталога из пути и функцию basename для получения имени файла.

# Base.pkgdirMethod

pkgdir(m::Module[, paths::String...])

Возвращает корневой каталог пакета, из которого был импортирован модуль m, или значение nothing, если модуль m не был импортирован из пакета. При необходимости можно указать компоненты пути, из которых составляется путь внутри корневого каталога пакета.

Для получения корневого каталога пакета, из которого был импортирован модуль, можно использовать форму pkgdir(@__MODULE__).

julia> pkgdir(Foo)
"/path/to/Foo.jl"

julia> pkgdir(Foo, "src", "file.jl")
"/path/to/Foo.jl/src/file.jl"
Совместимость: Julia 1.7

Для использования необязательного аргумента paths требуется версия Julia не ниже 1.7.

# Base.pkgversionMethod

pkgversion(m::Module)

Возвращает версию пакета, из которого был импортирован модуль m, или значение nothing, если модуль m не был импортирован из пакета, или импортирован из пакета без значения в поле версии.

Версия считывается из файла Project.toml пакета во время загрузки пакета.

Для получения версии пакета, из которого был импортирован модуль, можно использовать форму pkgversion(@__MODULE__).

Совместимость: Julia 1.9

Эта функция появилась в версии Julia 1.9.

# Base.modulerootFunction

moduleroot(m::Module) -> Module

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

# __module__Keyword

__module__

Аргумент __module__ доступен только внутри макроса и предоставляет информацию (в форме объекта Module) о контексте расширения вызова макроса. Дополнительные сведения см. в разделе руководства, посвященном вызову макросов.

# __source__Keyword

__source__

Аргумент __source__ доступен только внутри макроса и предоставляет информацию (в форме объекта LineNumberNode) о расположении анализатора для символа @ в вызове макроса. Дополнительные сведения см. в разделе руководства, посвященном вызову макросов.

# Base.@__MODULE__Macro

@__MODULE__ -> Module

Возвращает модуль Module, с которым связан вызов eval верхнего уровня, то есть Module, из которого в настоящее время считывается код.

# Base.@__FILE__Macro

@__FILE__ -> AbstractString

Расширяется в строку с путем к файлу, который содержит вызов макроса, или в пустую строку при вычислении с помощью julia -e <expr>. Если отсутствует информация об исходном коде анализатора, возвращает значение nothing. См. также описание константы PROGRAM_FILE.

# Base.@__DIR__Macro

@__DIR__ -> AbstractString

Расширяется в строку с абсолютным путем к каталогу с файлом, который содержит вызов макроса. При запуске из REPL или вычислении с помощью julia -e <expr> возвращает текущий рабочий каталог.

# Base.@__LINE__Macro

@__LINE__ -> Int

Расширяется в номер строки, в которой происходит вызов макроса. Если определить номер строки не удалось, возвращает значение 0.

# Base.fullnameFunction

fullname(m::Module)

Возвращает полное имя модуля в виде кортежа Например,

Примеры

julia> fullname(Base.Iterators)
(:Base, :Iterators)

julia> fullname(Main)
(:Main,)

# Base.namesFunction

names(x::Module; all::Bool = false, imported::Bool = false)

Возвращает массив имен, экспортируемых модулем Module, исключая устаревшие имена. Если аргумент all равен true, в список также включаются неэкспортируемые имена, определенные в модуле, устаревшие имена и имена, генерируемые компилятором. Если аргумент imported равен true, также включаются имена, экспортируемые из других модулей явным образом.

Имена, определенные в модуле Main, представляют собой особый случай: все они считаются экспортируемыми, так как в Julia имена не экспортируются из Main явным образом.

См. также описание @locals, @__MODULE__.

# Base.nameofMethod

nameof(f::Function) -> Symbol

Возвращает имя универсальной функции Function в виде символа. Для анонимных функций это имя генерируется компилятором. Для явно объявленных подтипов Function это имя типа функции.

# Base.functionlocMethod

functionloc(f::Function, types)

Возвращает кортеж (filename,line) с расположением определения универсальной функции Function.

# Base.functionlocMethod

functionloc(m::Method)

Возвращает кортеж (filename,line) с расположением определения метода Method.

# Base.@localsMacro

@locals()

Создает словарь, который содержит имена (в виде символов) и значения всех локальных переменных, определенных начиная с места вызова.

Совместимость: Julia 1.1

Для этого макроса требуется версия Julia не ниже 1.1.

Примеры

julia> let x = 1, y = 2
           Base.@locals
       end
Dict{Symbol, Any} with 2 entries:
  :y => 2
  :x => 1

julia> function f(x)
           local y
           show(Base.@locals); println()
           for i = 1:1
               show(Base.@locals); println()
           end
           y = 2
           show(Base.@locals); println()
           nothing
       end;

julia> f(42)
Dict{Symbol, Any}(:x => 42)
Dict{Symbol, Any}(:i => 1, :x => 42)
Dict{Symbol, Any}(:y => 2, :x => 42)

Загрузка кода

# Base.identify_packageFunction

Base.identify_package(name::String)::Union{PkgId, Nothing}
Base.identify_package(where::Union{Module,PkgId}, name::String)::Union{PkgId, Nothing}

Определяет пакет по его имени из текущего стека среды, возвращая его PkgId или nothing, если он не может быть найден.

Если указан только аргумент name, выполняет поиск каждой среды в стеке и ее именованных прямых зависимостей.

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

julia> Base.identify_package("Pkg") # Pkg является зависимостью среды по умолчанию
Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]

julia> using LinearAlgebra

julia> Base.identify_package(LinearAlgebra, "Pkg") # Pkg не является зависимостью линейной алгебры

# Base.locate_packageFunction

Base.locate_package(pkg::PkgId)::Union{String, Nothing}

Путь к файлу точки входа для пакета, соответствующего идентификатору pkg, или nothing, если он не найден. См. также описание identify_package.

julia> pkg = Base.identify_package("Pkg")
Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]

julia> Base.locate_package(pkg)
"/path/to/julia/stdlib/v1.9/Pkg/src/Pkg.jl"

# Base.requireFunction

require(into::Module, module::Symbol)

Эта функция реализуется в using или import, если модуль еще не определен в Main. Ее также можно вызывать напрямую для принудительной перезагрузки модуля, даже если он уже был загружен ранее (например, при интерактивной разработке библиотек).

Загружает файл исходного кода в контексте модуля Main на каждом активном узле, выполняя поиск стандартных расположений файлов. require считается операцией верхнего уровня, поэтому она задает текущий путь include, но не использует его для поиска файлов (см. справку по функции include). Эта функция обычно применяется для загрузки кода библиотеки и неявно вызывается командой using для загрузки пакетов.

При поиске файлов функция require сначала ищет код пакета в глобальном массиве LOAD_PATH. require требует соблюдения регистра символов на всех платформах, в том числе с файловыми системами без учета регистра, таких как macOS и Windows.

Дополнительные сведения о загрузке кода см. в разделах руководства, посвященных модулям и параллельным вычислениям.

# Base.compilecacheFunction

Base.compilecache(module::PkgId)

Создает предварительно скомпилированный файл кеша для модуля и всех его зависимостей. Позволяет сократить время загрузки пакета. Файлы кеша хранятся в папке DEPOT_PATH[1]/compiled. В разделе Инициализация и предварительная компиляция модуля приводятся важные примечания.

# Base.get_extensionFunction

get_extension(parent::Module, extension::Symbol)

Возвращает модуль для extension для parent или возвращает nothing, если расширение не загружено.

Внутренние компоненты

# Base.GC.gcFunction

GC.gc([full=true])

Выполняет сборку мусора. Аргумент full определяет тип сборки: при полной сборке (по умолчанию) очищаются все объекты, в результате чего следующая проверка сборщиком мусора будет выполняться гораздо медленнее, а при добавочной могут очищаться только так называемые «молодые» объекты.

Слишком частое использование, скорее всего, приведет к снижению производительности.

# Base.GC.enableFunction

GC.enable(on::Bool)

Включает или отключает сборку мусора с помощью логического аргумента (true — включена, false — отключена). Возвращает предыдущее состояние сборки мусора.

Отключать сборку мусора следует с осторожностью, так как это может привести к неограниченному росту потребления памяти.

# Base.GC.@preserveMacro

GC.@preserve x1 x2 ... xn expr

Помечает объекты x1, x2, ... как используемые во время вычисления выражения expr. Требуется только в небезопасном коде, когда выражение expr неявным образом использует память или другие ресурсы, принадлежащие одному или нескольким объектам x.

Под неявным использованием объекта x понимается любое косвенное использование ресурсов, логически принадлежащих x, незаметное для компилятора. Некоторые примеры:

  • прямой доступ к памяти объекта посредством Ptr;

  • передача указателя на объект x в вызов ccall;

  • использование ресурсов объекта x, которые будут высвобождены финализатором.

В стандартных ситуациях макрос @preserve обычно не оказывает влияния на производительность, так как время существования объектов увеличивается незначительно. Реализация макроса @preserve может иметь такие последствия, как защита объектов, динамически размещаемых в памяти, от сборки коллекции.

Примеры

При загрузке по указателю с помощью unsafe_load базовый объект используется неявным образом. Например, объект x неявно используется функцией unsafe_load(p) в следующем коде:

julia> let
           x = Ref{Int}(101)
           p = Base.unsafe_convert(Ptr{Int}, x)
           GC.@preserve x unsafe_load(p)
       end
101

При передаче указателей в ccall объект, на который ссылается указатель, используется неявным образом и должен сохраняться. (Однако имейте в виду, что обычно объект x передается в ccall напрямую, что считается явным использованием.)

julia> let
           x = "Hello"
           p = pointer(x)
           Int(GC.@preserve x @ccall strlen(p::Cstring)::Csize_t)
           # Предпочтительная альтернатива
           Int(@ccall strlen(x::Cstring)::Csize_t)
       end
5

# Base.GC.safepointFunction

GC.safepoint()

Добавляет в программу точку, где может быть выполнена сборка мусора. Может быть полезно в редких случаях, когда в многопоточной программе некоторые потоки выделяют память под объекты (и поэтому им может потребоваться сборка мусора), а другие выполняют только простые операции (без выделения памяти, переключения задач или ввода-вывода). Периодический вызов этой функции в потоках, не выделяющих память, позволяет проводить сборку мусора.

Совместимость: Julia 1.4

Эта функция впервые реализована в Julia 1.4.

# Base.GC.enable_loggingFunction

GC.enable_logging(on::Bool)

Когда аргумент on имеет значение true, выводит статистику по каждой сборке мусора в поток stderr.

# Base.Meta.lowerFunction

lower(m, x)

Принимает выражение x и возвращает эквивалентное выражение в пониженной форме для выполнения в модуле m. См. также описание code_lowered.

# Base.Meta.@lowerMacro

@lower [m] x

Возвращает пониженную форму выражения x в модуле m. По умолчанию m — это модуль, в котором вызывается макрос. См. также описание lower.

# Base.Meta.parseMethod

parse(str, start; greedy=true, raise=true, depwarn=true)

Анализирует строку, содержащую выражение, и возвращает выражение (которое далее может быть передано в функцию eval для выполнения). start — это индекс кодовой единицы, соответствующей первому символу в строке str, с которого должен начинаться анализ (как и обычно при обращении к строкам по индексам, это не индекс символа). Если аргумент greedy имеет значение true (по умолчанию), функция parse попытается обработать как можно больше данных. В противном случае обработка остановится, как только будет проанализировано допустимое выражение. Для неполных, но в остальном синтаксически допустимых выражений возвращается Expr(:incomplete, "(error message)"). Если аргумент raise имеет значение true (по умолчанию), при обнаружении синтаксических ошибок (исключая неполноту выражения) возникает ошибка. Если raise равен false, функция parse вернет выражение, при вычислении которого возникнет ошибка. Если аргумент depwarn имеет значение false, предупреждения о выводе из использования не выдаются.

julia> Meta.parse("(α, β) = 3, 5", 1) # начало строки
(:((α, β) = (3, 5)), 16)

julia> Meta.parse("(α, β) = 3, 5", 1, greedy=false)
(:((α, β)), 9)

julia> Meta.parse("(α, β) = 3, 5", 16) # конец строки
(nothing, 16)

julia> Meta.parse("(α, β) = 3, 5", 11) # индекс 3
(:((3, 5)), 16)

julia> Meta.parse("(α, β) = 3, 5", 11, greedy=false)
(3, 13)

# Base.Meta.parseMethod

parse(str; raise=true, depwarn=true)

Анализирует как можно большую часть строки, содержащей выражение, и возвращает одно выражение. Если после первого выражения есть еще символы, происходит ошибка. Если аргумент raise имеет значение true (по умолчанию), при обнаружении синтаксических ошибок возникает ошибка; в противном случае функция parse вернет выражение, при выполнении которого возникнет ошибка. Если аргумент depwarn имеет значение false, предупреждения о выводе из использования не выдаются.

julia> Meta.parse("x = 3")
:(x = 3)

julia> Meta.parse("x = ")
:($(Expr(:incomplete, "incomplete: premature end of input")))

julia> Meta.parse("1.0.2")
ERROR: Base.Meta.ParseError("invalid numeric constant \"1.0.\"")
Stacktrace:
[...]

julia> Meta.parse("1.0.2"; raise = false)
:($(Expr(:error, "invalid numeric constant \"1.0.\"")))

# Base.Meta.ParseErrorType

ParseError(msg)

Выражение, переданное в функцию parse, не распознано как допустимое выражение Julia.

# Core.QuoteNodeType

QuoteNode

Цитируемый фрагмент кода, который не поддерживает интерполяцию. Подробные сведения см. в разделе руководства, посвященном QuoteNode.

# Base.macroexpandFunction

macroexpand(m::Module, x; recursive=true)

Принимает выражение x и возвращает эквивалентное выражение, в котором удалены (расширены) все макросы, для выполнения в модуле m. Именованный аргумент recursive определяет, расширяются ли более глубокие уровни вложенных макросов. Это демонстрируется в следующем примере:

julia> module M
           macro m1()
               42
           end
           macro m2()
               :(@m1())
           end
       end
M

julia> macroexpand(M, :(@m2()), recursive=true)
42

julia> macroexpand(M, :(@m2()), recursive=false)
:(#= REPL[16]:6 =# M.@m1)

# Base.@macroexpandMacro

@macroexpand

Возвращает эквивалентное выражение, в котором удалены (расширены) все макросы.

Между макросом @macroexpand и функцией macroexpand есть различия.

  • Функция macroexpand принимает именованный аргумент recursive, а макрос @macroexpand всегда работает рекурсивно. Версия этого макроса без рекурсии — @macroexpand1.

  • У функции macroexpand есть явно задаваемый аргумент module, а макрос @macroexpand всегда выполняет расширение относительно модуля, в котором вызывается.

Это хорошо видно в следующем примере.

julia> module M
           macro m()
               1
           end
           function f()
               (@macroexpand(@m),
                macroexpand(M, :(@m)),
                macroexpand(Main, :(@m))
               )
           end
       end
M

julia> macro m()
           2
       end
@m (macro with 1 method)

julia> M.f()
(1, 1, 2)

При использовании @macroexpand выражение расширяется там, где макрос @macroexpand используется в коде (в примере это модуль M). При использовании macroexpand выражение расширяется в модуле, указанном в первом аргументе.

# Base.@macroexpand1Macro

@macroexpand1

Версия макроса @macroexpand без рекурсии.

# Base.code_loweredFunction

code_lowered(f, types; generated=true, debuginfo=:default)

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

Если аргумент generated равен false, возвращаемые экземпляры CodeInfo соответствуют стандартным реализациям. Если стандартной реализации нет, возникает ошибка. Если аргумент generated равен true, эти экземпляры CodeInfo соответствуют телам методов, которые получаются в результате расширения генераторов.

Именованный аргумент debuginfo определяет объем метаданных кода в выходных данных.

Обратите внимание: если типы в types не являются конечными, когда аргумент generated равен true и любой соответствующий метод помечен как @generated, возникает ошибка.

# Base.code_typedFunction

code_typed(f, types; kw...)

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

Именованные аргументы

  • optimize=true: определяет, применяются ли дополнительные оптимизации, такие как встраивание.

  • debuginfo=:default: определяет объем метаданных кода в выходных данных.

Возможные значения: :source и :none.

Внутренние именованные аргументы

Этот раздел предназначен только для тех, кто разбирается во внутренних принципах работы компилятора Julia.

  • world=Base.get_world_counter(): необязательный, определяет «возраст мира», используемый при поиске методов.

Если этот аргумент не задан, используется текущий «возраст мира».

  • interp=Core.Compiler.NativeInterpreter(world): необязательный, определяет используемый интерпретатор.

Если этот аргумент не задан, используется собственный интерпретатор Julia.

Пример

Типы аргументов можно указать в виде кортежа, чтобы получить соответствующий результат функции code_typed.

julia> code_typed(+, (Float64, Float64))
1-element Vector{Any}:
 CodeInfo(
1 ─ %1 = Base.add_float(x, y)::Float64
└──      return %1
) => Float64

# Base.precompileFunction

precompile(f, argtypes::Tuple{Vararg{Any}})

Компилирует указанную функцию f с учетом типов аргументов, переданных в виде кортежа в argtypes, но не выполняет ее.

precompile(f, argtypes::Tuple{Vararg{Any}}, m::Method)

Выполняет предварительную компиляцию определенного метода для заданных типов аргументов. Можно использовать для предварительной компиляции метода, отличного от того, который обычно выбирается при диспетчеризации, имитируя таким образом invoke.

# Base.jit_total_bytesFunction

Base.jit_total_bytes()

Возвращает общий объем памяти (в байтах), выделенной JIT-компилятором, например для машинного кода и данных.

Метафункции

# Base.Meta.quotFunction

Meta.quot(ex)::Expr

Цитирует выражение ex, создавая выражения с заголовком quote. Может использоваться, например, для представления объектов типа Expr в AST. См. также раздел руководства, посвященный QuoteNode.

Примеры

julia> eval(Meta.quot(:x))
:x

julia> dump(Meta.quot(:x))
Expr
  head: Symbol quote
  args: Array{Any}((1,))
    1: Symbol x

julia> eval(Meta.quot(:(1+2)))
:(1 + 2)

# Base.isexprFunction

Meta.isexpr(ex, head[, n])::Bool

Возвращает значение true, если ex — это объект Expr указанного типа head. Также можно проверить, равно ли количество его аргументов значению n. Аргумент head может содержать объект типа Symbol или коллекцию объектов Symbol. Например, чтобы проверить, было ли макросу передано выражение вызова функции, можно использовать isexpr(ex, :call).

Примеры

julia> ex = :(f(x))
:(f(x))

julia> Meta.isexpr(ex, :block)
false

julia> Meta.isexpr(ex, :call)
true

julia> Meta.isexpr(ex, [:block, :call]) # несколько возможных заголовков
true

julia> Meta.isexpr(ex, :call, 1)
false

julia> Meta.isexpr(ex, :call, 2)
true

# Base.isidentifierFunction

 isidentifier(s) -> Bool

Определяет, содержит ли символ или строка s символы, которые анализируются в коде Julia как обычное допустимое имя (а не бинарный или унарный оператор). См. также описание функции Base.isoperator.

В объектах Symbol в Julia допускаются любые последовательности символов (кроме \0), поэтому макросы автоматически используют имена переменных с символом # во избежание конфликтов имен с окружающим кодом. Чтобы анализатор мог распознавать переменные, применяется ограниченный набор символов (который существенно расширяется благодаря Юникоду). Функция isidentifier() позволяет напрямую запросить у анализатора, содержит ли объект Symbol допустимые символы.

Примеры

julia> Meta.isidentifier(:x), Meta.isidentifier("1x")
(true, false)

# Base.isoperatorFunction

isoperator(s::Symbol)

Возвращает значение true, если символ можно использовать в качестве оператора; в противном случае возвращает false.

Примеры

julia> Meta.isoperator(:+), Meta.isoperator(:f)
(true, false)

# Base.isunaryoperatorFunction

isunaryoperator(s::Symbol)

Возвращает значение true, если символ можно использовать в качестве унарного (префиксного) оператора; в противном случае возвращает false.

Примеры

julia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f)
(true, true, false)

# Base.isbinaryoperatorFunction

isbinaryoperator(s::Symbol)

Возвращает значение true, если символ можно использовать в качестве бинарного (инфиксного) оператора; в противном случае возвращает false.

Примеры

julia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f)
(true, false, false)

# Base.Meta.show_sexprFunction

Meta.show_sexpr([io::IO,], ex)

Выводит изображение ex в виде S-выражения в стиле Лиспа.

Примеры

julia> Meta.show_sexpr(:(f(x, g(y,z))))
(:call, :f, :x, (:call, :g, :y, :z))