Essentials
Introduction
Julia Base содержит ряд функций и макросов, подходящих для выполнения научных и численных вычислений, но также так же широк, как и многие языки программирования общего назначения. Дополнительная функциональность доступна из растущей коллекции available packages. Функции сгруппированы по темам ниже.
Некоторые общие заметки:
- Чтобы использовать функции модуля, используйте
import Module
для импорта модуля иModule.fn(x)
для использования функций. - В качестве альтернативы,
using Module
импортирует все экспортированные функцииModule
в текущее пространство имен. - По соглашению, имена функций, заканчивающиеся на восклицательный знак (
!
), изменяют свои аргументы. Некоторые функции имеют как изменяющие (например,sort!
), так и неизменяющие (sort
) версии.
Поведение Base
и стандартных библиотек стабильно, как определено в SemVer, только если они задокументированы; т.е. включены в Julia documentation и не помечены как нестабильные. См. API FAQ для получения дополнительной информации.
Getting Around
Base.exit
— Functionexit(code=0)
Остановите программу с кодом выхода. Код выхода по умолчанию равен нулю, что указывает на успешное завершение программы. В интерактивной сессии exit()
можно вызвать с помощью сочетания клавиш ^D
.
Base.atexit
— Functionatexit(f)
Зарегистрируйте функцию с нулем или одним аргументом f()
, которая будет вызвана при выходе из процесса. Хуки atexit()
вызываются в порядке последнего зарегистрированного, первого вызванного (LIFO) и выполняются перед финализаторами объектов.
Если для f
определен метод с одним целым аргументом, он будет вызван как f(n::Int32)
, где n
— текущий код выхода, в противном случае он будет вызван как f()
.
Форма с одним аргументом требует Julia 1.9
Хуки выхода могут вызывать exit(n)
, в этом случае Julia завершит работу с кодом выхода n
(вместо оригинального кода выхода). Если более одного хука выхода вызывает exit(n)
, то Julia завершит работу с кодом выхода, соответствующим последнему вызванному хуку выхода, который вызывает exit(n)
. (Поскольку хуки выхода вызываются в порядке LIFO, "последний вызванный" эквивалентен "первый зарегистрированный".)
Примечание: После того как все хуки выхода были вызваны, больше никаких хуков выхода нельзя зарегистрировать, и любой вызов atexit(f)
после завершения всех хуков вызовет исключение. Эта ситуация может возникнуть, если вы регистрируете хуки выхода из фоновых задач, которые могут все еще выполняться одновременно во время завершения работы.
Base.isinteractive
— Functionisinteractive() -> Bool
Определяет, работает ли Julia в интерактивной сессии.
Base.summarysize
— FunctionBase.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.include
— FunctionBase.include([mapexpr::Function,] m::Module, path::AbstractString)
Оценивает содержимое входного исходного файла в глобальной области модуля m
. Каждый модуль (за исключением тех, которые определены с помощью baremodule
) имеет собственное определение include
, опуская аргумент m
, что оценивает файл в этом модуле. Возвращает результат последнего оцененного выражения входного файла. Во время включения путь к файлу, локальный для задачи, устанавливается в директорию, содержащую файл. Вложенные вызовы include
будут искать относительно этого пути. Эта функция обычно используется для интерактивной загрузки исходного кода или для объединения файлов в пакетах, которые разбиты на несколько исходных файлов.
Необязательный первый аргумент mapexpr
может быть использован для преобразования включенного кода перед его оценкой: для каждого разобранного выражения expr
в path
функция include
фактически оценивает mapexpr(expr)
. Если он опущен, mapexpr
по умолчанию равен identity
.
Для передачи аргумента mapexpr
требуется Julia 1.5.
include
— Functioninclude([mapexpr::Function,] path::AbstractString)
Оцените содержимое входного исходного файла в глобальной области видимости содержащего модуля. Каждый модуль (за исключением тех, которые определены с помощью baremodule
) имеет свое собственное определение include
, которое оценивает файл в этом модуле. Возвращает результат последнего оцененного выражения входного файла. Во время включения устанавливается локальный путь включения, указывающий на директорию, содержащую файл. Вложенные вызовы include
будут искать относительно этого пути. Эта функция обычно используется для интерактивной загрузки исходного кода или для объединения файлов в пакетах, которые разбиты на несколько исходных файлов. Аргумент path
нормализуется с использованием normpath
, который разрешает относительные токены пути, такие как ..
, и преобразует /
в соответствующий разделитель пути.
Необязательный первый аргумент mapexpr
может быть использован для преобразования включенного кода перед его оценкой: для каждого разобранного выражения expr
в path
функция include
фактически оценивает mapexpr(expr)
. Если он опущен, mapexpr
по умолчанию равен identity
.
Используйте Base.include
, чтобы оценить файл в другом модуле.
Для передачи аргумента mapexpr
требуется Julia 1.5.
Base.include_string
— Functioninclude_string([mapexpr::Function,] m::Module, code::AbstractString, filename::AbstractString="string")
Как и include
, за исключением того, что код читается из данной строки, а не из файла.
Необязательный первый аргумент mapexpr
может быть использован для преобразования включенного кода перед его выполнением: для каждого разобранного выражения expr
в code
функция include_string
фактически выполняет mapexpr(expr)
. Если он опущен, mapexpr
по умолчанию равен identity
.
Для передачи аргумента mapexpr
требуется Julia 1.5.
Base.include_dependency
— Functioninclude_dependency(path::AbstractString; track_content::Bool=true)
В модуле объявите, что файл, директория или символическая ссылка, указанная в path
(относительная или абсолютная), является зависимостью для предварительной компиляции; то есть, если track_content=true
, модуль потребуется перекомпилировать, если содержимое path
изменится (если path
является директорией, содержимое равно join(readdir(path))
). Если track_content=false
, перекомпиляция запускается, когда время изменения mtime
path
изменяется.
Это необходимо только в том случае, если ваш модуль зависит от пути, который не используется через include
. Это не имеет эффекта вне компиляции.
Ключевой аргумент track_content
требует как минимум Julia 1.11. Теперь возникает ошибка, если path
не читаем.
__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.which
— Methodwhich(f, types)
Возвращает метод f
(объект Method
), который будет вызван для аргументов заданных types
.
Если types
является абстрактным типом, то возвращается метод, который будет вызван с помощью invoke
.
Смотрите также: parentmodule
, @which
, и @edit
.
Base.methods
— Functionmethods(f, [types], [module])
Возвращает таблицу методов для f
.
Если указаны types
, возвращает массив методов, типы которых совпадают. Если указан module
, возвращает массив методов, определенных в этом модуле. Также можно указать список модулей в виде массива.
Для указания модуля требуется как минимум Julia 1.4.
См. также: which
, @which
и methodswith
.
Base.@show
— Macro@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
Base.MainInclude.ans
— Constantans
Переменная, ссылающаяся на последнее вычисленное значение, автоматически импортируемая в интерактивный интерфейс.
Base.MainInclude.err
— Constanterr
Переменная, ссылающаяся на последние выброшенные ошибки, автоматически импортируемая в интерактивный интерфейс. Выброшенные ошибки собираются в стек исключений.
Base.active_project
— Functionactive_project()
Возвращает путь к активному файлу Project.toml
. См. также Base.set_active_project
.
Base.set_active_project
— Functionset_active_project(projfile::Union{AbstractString,Nothing})
Установите активный файл Project.toml
на projfile
. См. также Base.active_project
.
Эта функция требует как минимум Julia 1.8.
Keywords
Это список зарезервированных ключевых слов в 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
разбираются как инфиксные операторы; public
разбирается как ключевое слово, когда начинается верхнеуровневое выражение; outer
разбирается как ключевое слово, когда используется для изменения области видимости переменной в спецификации итерации цикла for
; и as
используется как ключевое слово для переименования идентификатора, введенного в область видимости с помощью import
или using
. Тем не менее, создание переменных с именами where
, in
, isa
, outer
и as
разрешено.
module
— Keywordмодуль
модуль
объявляет Module
, который является отдельным рабочим пространством глобальных переменных. Внутри модуля вы можете контролировать, какие имена из других модулей видимы (через импорт), и указывать, какие из ваших имен предназначены для публичного использования (через export
и public
). Модули позволяют вам создавать определения верхнего уровня, не беспокоясь о конфликтах имен, когда ваш код используется вместе с кодом других людей. См. раздел руководства о модулях для получения дополнительной информации.
Примеры
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
export
— Keywordexport
export
используется в модулях, чтобы сообщить Julia, какие имена должны быть доступны пользователю. Например: export foo
делает имя foo
доступным при using
модуля. См. раздел руководства о модулях для получения подробной информации.
public
— Keywordpublic
public
используется в модулях, чтобы сообщить Julia, какие имена являются частью публичного API модуля. Например: public foo
указывает, что имя foo
является публичным, не делая его доступным при using
модуля. См. раздел руководства о модулях для получения подробной информации.
Ключевое слово public было добавлено в Julia 1.11. До этого понятие публичности было менее явным.
import
— Keywordimport
import Foo
загрузит модуль или пакет Foo
. Имена из импортированного модуля Foo
можно получить с помощью синтаксиса с точкой (например, Foo.foo
для доступа к имени foo
). См. раздел руководства о модулях для получения подробной информации.
using
— Keywordusing
using Foo
загрузит модуль или пакет Foo
и сделает его export
ированные имена доступными для прямого использования. Имена также могут использоваться через синтаксис точки (например, Foo.foo
для доступа к имени foo
), независимо от того, являются ли они export
ированными или нет. См. раздел руководства о модулях для получения подробной информации.
Когда два или более пакетов/модулей экспортируют имя, и это имя не относится к одному и тому же в каждом из пакетов, и пакеты загружаются через using
без явного списка имен, то ссылка на это имя без квалификации является ошибкой. Поэтому рекомендуется, чтобы код, предназначенный для совместимости с будущими версиями его зависимостей и Julia, например, код в выпущенных пакетах, перечислял имена, которые он использует из каждого загруженного пакета, например, using Foo: Foo, f
, а не using Foo
.
as
— Keywordas
as
используется как ключевое слово для переименования идентификатора, введенного в область видимости с помощью import
или using
, с целью обхода конфликтов имен, а также для сокращения имен. (За пределами операторов import
или using
as
не является ключевым словом и может использоваться как обычный идентификатор.)
import LinearAlgebra as LA
вводит импортированную стандартную библиотеку LinearAlgebra
в область видимости как LA
.
import LinearAlgebra: eigen as eig, cholesky as chol
вводит методы eigen
и cholesky
из LinearAlgebra
в область видимости как eig
и chol
соответственно.
as
работает с using
только тогда, когда отдельные идентификаторы вводятся в область видимости. Например, using LinearAlgebra: eigen as eig
или using LinearAlgebra: eigen as eig, cholesky as chol
работает, но using LinearAlgebra as LA
является недопустимым синтаксисом, так как не имеет смысла переименовывать все экспортированные имена из LinearAlgebra
в LA
.
baremodule
— Keywordbaremodule
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
function
— Keywordфункция
Функции определяются с помощью ключевого слова function
:
function add(a, b)
return a + b
end
Или в короткой форме:
add(a, b) = a + b
Использование ключевого слова return
точно такое же, как и в других языках, но часто является необязательным. Функция без явного оператора return
вернет последнее выражение в теле функции.
macro
— Keywordмакрос
макрос
определяет метод для вставки сгенерированного кода в программу. Макрос сопоставляет последовательность выражений аргументов с возвращаемым выражением, и полученное выражение непосредственно подставляется в программу в точке, где вызывается макрос. Макросы — это способ выполнения сгенерированного кода без вызова eval
, поскольку сгенерированный код просто становится частью окружающей программы. Аргументы макроса могут включать выражения, литеральные значения и символы. Макросы могут быть определены для переменного числа аргументов (varargs), но не принимают именованные аргументы. Каждый макрос также неявно получает аргументы __source__
, который содержит номер строки и имя файла, из которого вызывается макрос, и __module__
, который является модулем, в котором макрос расширяется.
Смотрите раздел справки о Метапрограммировании для получения дополнительной информации о том, как написать макрос.
Примеры
julia> макрос sayhello(name)
return :( println("Hello, ", $name, "!") )
end
@sayhello (макрос с 1 методом)
julia> @sayhello "Charlie"
Hello, Charlie!
julia> макрос saylots(x...)
return :( println("Say: ", $(x...)) )
end
@saylots (макрос с 1 методом)
julia> @saylots "hey " "there " "friend"
Say: hey there friend
return
— Keywordreturn
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
вызывает преждевременное завершение всего текущего выражения верхнего уровня.
do
— Keyworddo
Создайте анонимную функцию и передайте её в качестве первого аргумента в вызов функции. Например:
map(1:10) do x
2x
end
эквивалентно map(x->2x, 1:10)
.
Используйте несколько аргументов следующим образом:
map(1:10, 11:20) do x, y
x + y
end
begin
— Keywordначало
begin...end
обозначает блок кода.
begin
println("Hello, ")
println("World!")
end
Обычно begin
не будет необходим, так как такие ключевые слова, как function
и let
, неявно начинают блоки кода. См. также ;
.
begin
также может использоваться при индексировании для обозначения первого индекса коллекции или первого индекса измерения массива. Например, a[begin]
— это первый элемент массива a
.
Использование begin
в качестве индекса требует Julia 1.4 или более поздней версии.
Примеры
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
end
— Keywordend
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
let
— Keywordlet
let
блоки создают новую жесткую область видимости и при необходимости вводят новые локальные привязки.
Точно так же, как и другие конструкции области видимости, let
блоки определяют блок кода, в котором новые локальные переменные доступны. Кроме того, синтаксис имеет особое значение для присваиваний, разделенных запятыми, и имен переменных, которые могут при необходимости появляться на той же строке, что и let
:
let var1 = value1, var2, var3 = value3
code
end
Переменные, введенные в этой строке, локальны для let
блока, и присваивания оцениваются по порядку, при этом каждая правая часть оценивается в области видимости, не учитывая имя слева. Поэтому имеет смысл писать что-то вроде let x = x
, поскольку две переменные x
различны, и левая часть локально затеняет x
из внешней области видимости. Это может быть даже полезной идиомой, так как новые локальные переменные создаются каждый раз, когда входите в локальные области видимости, но это наблюдается только в случае переменных, которые переживают свою область видимости через замыкания. Переменная let
без присваивания, такая как var2
в приведенном выше примере, объявляет новую локальную переменную, которая еще не связана со значением.
В отличие от этого, 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
if
— Keywordif/elseif/else
if
/elseif
/else
выполняет условную оценку, что позволяет частям кода оцениваться или не оцениваться в зависимости от значения булевого выражения. Вот анатомия синтаксиса условного оператора if
/elseif
/else
:
if x < y
println("x меньше y")
elseif x > y
println("x больше y")
else
println("x равен y")
end
Если условное выражение x < y
истинно, то соответствующий блок оценивается; в противном случае оценивается условное выражение x > y
, и если оно истинно, то соответствующий блок оценивается; если ни одно из выражений не истинно, оценивается блок else
. Блоки elseif
и else
являются необязательными, и можно использовать столько блоков elseif
, сколько необходимо.
В отличие от некоторых других языков, условия должны быть типа Bool
. Недостаточно, чтобы условия были преобразуемыми в Bool
.
julia> if 1 end
ERROR: TypeError: non-boolean (Int64) used in boolean context
for
— Keywordfor
for
циклы многократно выполняют блок операторов, перебирая последовательность значений.
Итерационная переменная всегда является новой переменной, даже если переменная с таким же именем существует в окружающей области видимости. Используйте outer
, чтобы повторно использовать существующую локальную переменную для итерации.
Примеры
julia> for i in [1, 4, 0]
println(i)
end
1
4
0
while
— Keywordwhile
while
циклы многократно оценивают условное выражение и продолжают оценивать тело цикла while, пока выражение остается истинным. Если условное выражение ложно, когда цикл while впервые достигается, тело никогда не оценивается.
Примеры
julia> i = 1
1
julia> while i < 5
println(i)
global i += 1
end
1
2
3
4
break
— Keywordbreak
Немедленно выйти из цикла.
Примеры
julia> i = 0
0
julia> while true
global i += 1
i > 5 && break
println(i)
end
1
2
3
4
5
continue
— Keywordпродолжить
Пропустить оставшуюся итерацию текущего цикла.
Примеры
julia> for i = 1:6
iseven(i) && continue
println(i)
end
1
3
5
try
— Keywordtry/catch
Оператор try
/catch
позволяет перехватывать ошибки (исключения), выбрасываемые throw
, чтобы выполнение программы могло продолжаться. Например, следующий код пытается записать файл, но предупреждает пользователя и продолжает выполнение вместо завершения, если файл не может быть записан:
try
open("/danger", "w") do f
println(f, "Hello")
end
catch
@warn "Не удалось записать файл."
end
или, когда файл не может быть прочитан в переменную:
lines = try
open("/danger", "r") do f
readlines(f)
end
catch
@warn "Файл не найден."
end
Синтаксис catch e
(где e
— это любая переменная) присваивает выброшенный объект исключения данной переменной внутри блока catch
.
Сила конструкции try
/catch
заключается в возможности немедленно развернуть глубоко вложенные вычисления на гораздо более высокий уровень в стеке вызывающих функций.
finally
— Keywordнаконец
Запустите некоторый код, когда данный блок кода завершится, независимо от того, как он завершится. Например, вот как мы можем гарантировать, что открытый файл будет закрыт:
f = open("file")
try
operate_on_file(f)
finally
close(f)
end
Когда управление покидает блок try
(например, из-за return
или просто нормального завершения), будет выполнено close(f)
. Если блок try
завершится из-за исключения, исключение продолжит распространяться. Блок catch
может быть объединен с try
и finally
. В этом случае блок finally
будет выполнен после того, как catch
обработает ошибку.
quote
— Keywordquote
quote
создает несколько объектов выражений в блоке без использования явного конструктора Expr
. Например:
ex = quote
x = 1
y = 2
x + y
end
В отличие от других способов цитирования, :( ... )
, эта форма вводит элементы QuoteNode
в дерево выражений, которые необходимо учитывать при прямом манипулировании деревом. Для других целей блоки :( ... )
и quote .. end
обрабатываются одинаково.
local
— Keywordlocal
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
global
— Keywordглобальный
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
outer
— Keywordfor 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: синтаксис: нет объявления внешней локальной переменной для "for outer"
[...]
const
— Keywordconst
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
вызывает предупреждение вместо ошибки. Однако это может привести к непредсказуемому поведению или испортить состояние вашей программы, поэтому этого следует избегать. Эта функция предназначена только для удобства во время интерактивного использования.
struct
— Keywordструктура
Наиболее часто используемым типом в Julia является структура, которая задается именем и набором полей.
struct Point
x
y
end
Поля могут иметь ограничения по типу, которые могут быть параметризованы:
struct Point{X}
x::X
y::Float64
end
Структура также может объявить абстрактный суперкласс с помощью синтаксиса <:
:
struct Point <: AbstractPoint
x
y
end
struct
по умолчанию неизменяемы; экземпляр одного из этих типов не может быть изменен после создания. Используйте mutable struct
, чтобы объявить тип, экземпляры которого могут быть изменены.
Смотрите раздел справочного руководства о Составных типах для получения дополнительной информации, такой как определение конструкторов.
mutable struct
— Keywordmutable struct
mutable struct
похож на struct
, но дополнительно позволяет устанавливать поля типа после создания.
Отдельные поля изменяемой структуры могут быть помечены как const
, чтобы сделать их неизменяемыми:
mutable struct Baz
a::Int
const b::Float64
end
Ключевое слово const
для полей изменяемых структур требует как минимум Julia 1.8.
Смотрите раздел справочника о Композитных типах для получения дополнительной информации.
Base.@kwdef
— Macro@kwdef typedef
Это вспомогательный макрос, который автоматически определяет конструктор на основе ключевых слов для типа, объявленного в выражении typedef
, которое должно быть выражением struct
или mutable struct
. Значение по умолчанию предоставляется путем объявления полей в форме field::T = default
или field = default
. Если значение по умолчанию не предоставлено, то аргумент ключевого слова становится обязательным аргументом ключевого слова в результирующем конструкторе типа.
Внутренние конструкторы все еще могут быть определены, но по крайней мере один из них должен принимать аргументы в той же форме, что и конструктор по умолчанию (т.е. один позиционный аргумент на поле), чтобы правильно функционировать с внешним конструктором на основе ключевых слов.
Base.@kwdef
для параметрических структур и структур с суперклассами требует как минимум Julia 1.1.
Этот макрос экспортируется начиная с 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: аргумент ключевого слова `b` не назначен
Stacktrace:
[...]
abstract type
— Keywordабстрактный тип
абстрактный тип
объявляет тип, который не может быть инстанцирован и служит только узлом в графе типов, тем самым описывая множества связанных конкретных типов: тех конкретных типов, которые являются его потомками. Абстрактные типы формируют концептуальную иерархию, которая делает систему типов Julia более чем просто коллекцией реализаций объектов. Например:
абстрактный тип Число конец
абстрактный тип Реальный <: Число конец
Число
не имеет супертиипа, в то время как Реальный
является абстрактным подтипом Число
.
primitive type
— Keywordпримитивный тип
примитивный тип
объявляет конкретный тип, данные которого состоят только из серии битов. Классическими примерами примитивных типов являются целые числа и числа с плавающей запятой. Вот несколько примеров объявлений встроенных примитивных типов:
примитивный тип Char 32 конец
примитивный тип Bool <: Integer 8 конец
Число после имени указывает, сколько битов памяти требуется для данного типа. В настоящее время поддерживаются только размеры, которые являются кратными 8 битам. Объявление Bool
показывает, как примитивный тип может быть дополнительно объявлен как подтип некоторого супертиипа.
where
— Keywordгде
Ключевое слово где
создает тип UnionAll
, который можно рассматривать как итеративное объединение других типов, по всем значениям некоторой переменной. Например, Vector{T} где T<:Real
включает все Vector
, где тип элемента является каким-то числом Real
.
По умолчанию граница переменной устанавливается на Any
, если она опущена:
Vector{T} где T # сокращение для `где T<:Any`
Переменные также могут иметь нижние границы:
Vector{T} где T>:Int
Vector{T} где Int<:T<:Real
Существует также краткий синтаксис для вложенных выражений где
. Например, это:
Pair{T, S} где S<:Array{T} где T<:Number
можно сократить до:
Pair{T, S} где {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, как и во многих языках, подобных C, и используется для разделения конца предыдущего выражения.
;
не обязателен в конце строки, но может использоваться для разделения выражений в одной строке или для объединения выражений в одно.
Добавление ;
в конце строки в REPL подавляет вывод результата этого выражения.
В объявлениях функций, а также опционально в вызовах, ;
разделяет обычные аргументы от ключевых.
В литералах массивов аргументы, разделенные точками с запятой, объединяются вместе. Разделитель, состоящий из одной ;
, объединяет вертикально (т.е. по первому измерению), ;;
объединяет горизонтально (второе измерение), ;;;
объединяет по третьему измерению и т.д. Такой разделитель также может использоваться в последней позиции в квадратных скобках для добавления завершающих измерений длиной 1.
;
в первой позиции внутри скобок может использоваться для создания именованного кортежа. Тот же синтаксис (; ...)
с левой стороны присваивания позволяет выполнять деструктуризацию свойств.
В стандартном 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> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> [1; 3;; 2; 4;;; 10*A]
2×2×2 Array{Int64, 3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
10 20
30 40
julia> [2; 3;;;]
2×1×1 Array{Int64, 3}:
[:, :, 1] =
2
3
julia> nt = (; x=1) # без ; или завершающей запятой это присвоит x
(x = 1,)
julia> key = :a; c = 3;
julia> nt2 = (; key => 1, b=2, c, nt.x)
(a = 1, b = 2, c = 3, x = 1)
julia> (; b, x) = nt2; # установить переменные b и x, используя деструктуризацию свойств
julia> b, x
(2, 1)
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
вызываетsetindex!
(a,v,i)
.a.b = c
вызываетsetproperty!
(a,:b,c)
.- Внутри вызова функции,
f(a=b)
передаетb
как значение аргумента ключевого словаa
. - Внутри скобок с запятыми,
(a=1,)
создаетNamedTuple
.
Примеры
Присваивание a
значению b
не создает копию 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) # in-place & thus more efficient than a = a[a .> 1]
2-element Array{Int64, 1}:
2
3
?:
— Keyworda ? 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("x is not larger")
x is not larger
julia> x > y ? "x is larger" : x == y ? "x and y are equal" : "y is larger"
"y is larger"
Standard Modules
Main
— ModuleГлавный
Главный
- это модуль верхнего уровня, и Julia начинает с Главный
, установленным в качестве текущего модуля. Переменные, определенные в командной строке, попадают в Главный
, а varinfo
перечисляет переменные в Главный
.
julia> @__MODULE__
Главный
Core
— ModuleCore
Core
— это модуль, который содержит все идентификаторы, считающиеся "встроенными" в язык, т.е. частью основного языка, а не библиотек. Каждый модуль неявно указывает using Core
, так как вы не можете ничего сделать без этих определений.
Base
— ModuleBase
Библиотека базового уровня Julia. Base
— это модуль, который содержит основную функциональность (содержимое base/
). Все модули неявно содержат using Base
, так как это необходимо в подавляющем большинстве случаев.
Base Submodules
Base.Broadcast
— ModuleBase.Broadcast
Модуль, содержащий реализацию широковещательной передачи.
Base.Docs
— ModuleДокументация
Модуль Docs
предоставляет макрос @doc
, который можно использовать для установки и получения метаданных документации для объектов Julia.
Пожалуйста, смотрите раздел руководства по документации для получения дополнительной информации.
Base.Iterators
— ModuleМетоды работы с итераторами.
Base.Libc
— ModuleИнтерфейс к libc, стандартной библиотеке C.
Base.Meta
— ModuleУдобные функции для метапрограммирования.
Base.StackTraces
— ModuleИнструменты для сбора и манипулирования трассировками стека. В основном используются для создания ошибок.
Base.Sys
— ModuleПредоставьте методы для получения информации о аппаратном обеспечении и операционной системе.
Base.Threads
— ModuleПоддержка многопоточности.
Base.GC
— ModuleBase.GC
Модуль с утилитами для сборки мусора.
All Objects
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.isa
— Functionisa(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.isequal
— Functionisequal(x, y) -> Bool
Похоже на ==
, за исключением обработки чисел с плавающей запятой и отсутствующих значений. 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.isless
— Functionisless(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.isunordered
— Functionisunordered(x)
Возвращает true
, если x
— это значение, которое не может быть упорядочено в соответствии с <
, такое как NaN
или missing
.
Значения, которые оцениваются как true
с помощью этого предиката, могут быть упорядочены относительно других порядков, таких как isless
.
Эта функция требует Julia 1.7 или более поздней версии.
Base.ifelse
— Functionifelse(condition::Bool, x, y)
Возвращает x
, если condition
равно true
, в противном случае возвращает y
. Это отличается от ?
или if
тем, что это обычная функция, поэтому все аргументы сначала вычисляются. В некоторых случаях использование ifelse
вместо оператора if
может устранить ветвление в сгенерированном коде и обеспечить более высокую производительность в узких циклах.
Примеры
julia> ifelse(1 > 2, 1, 2)
2
Core.typeassert
— Functiontypeassert(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.typeof
— Functiontypeof(x)
Получите конкретный тип x
.
Смотрите также eltype
.
Примеры
julia> a = 1//2;
julia> typeof(a)
Rational{Int64}
julia> M = [1 2; 3.5 4];
julia> typeof(M)
Matrix{Float64} (псевдоним для Array{Float64, 2})
Core.tuple
— Functiontuple(xs...)
Создайте кортеж из заданных объектов.
Смотрите также Tuple
, ntuple
, NamedTuple
.
Примеры
julia> tuple(1, 'b', pi)
(1, 'b', π)
julia> ans === (1, 'b', π)
true
julia> Tuple(Real[1, 2, pi]) # принимает коллекцию
(1, 2, π)
Base.ntuple
— Functionntuple(f, 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.objectid
— Functionobjectid(x) -> UInt
Получите хеш-значение для x
на основе идентичности объекта.
Если x === y
, то objectid(x) == objectid(y)
, и обычно, когда x !== y
, objectid(x) != objectid(y)
.
Base.hash
— Functionhash(x[, h::UInt]) -> UInt
Вычисляет целочисленный хеш-код так, что isequal(x,y)
подразумевает hash(x)==hash(y)
. Необязательный второй аргумент h
— это другой хеш-код, который будет смешан с результатом.
Новые типы должны реализовать форму с 2 аргументами, обычно вызывая метод hash
с 2 аргументами рекурсивно, чтобы смешать хеши содержимого друг с другом (и с h
). Обычно любой тип, который реализует hash
, также должен реализовать свой собственный ==
(следовательно, isequal
), чтобы гарантировать вышеупомянутое свойство.
Значение хеша может измениться, когда запускается новый процесс Julia.
julia> a = hash(10)
0x95ea2955abd45275
julia> hash(10, a) # используйте только вывод другой хеш-функции в качестве второго аргумента
0xd42bad54a8575b16
Base.finalizer
— Functionfinalizer(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.finalize
— Functionfinalize(x)
Немедленно выполните финализаторы, зарегистрированные для объекта x
.
Base.copy
— Functioncopy(x)
Создает поверхностную копию x
: внешняя структура копируется, но не все внутренние значения. Например, копирование массива создает новый массив с идентичными элементами, как у оригинала.
Base.deepcopy
— Functiondeepcopy(x)
Создает глубокую копию x
: все копируется рекурсивно, в результате чего получается полностью независимый объект. Например, глубокое копирование массива создает глубокие копии всех объектов, которые он содержит, и производит новый массив с согласованной структурой отношений (например, если первые два элемента являются одним и тем же объектом в исходном массиве, первые два элемента нового массива также будут одним и тем же объектом, скопированным с помощью deepcopy
). Вызов deepcopy
на объекте обычно должен иметь такой же эффект, как сериализация, а затем десериализация.
Хотя это обычно не требуется, пользовательские типы могут переопределить поведение по умолчанию deepcopy
, определив специализированную версию функции deepcopy_internal(x::T, dict::IdDict)
(которая в противном случае не должна использоваться), где T
— это тип, для которого будет специализировано, а dict
отслеживает объекты, скопированные до сих пор в процессе рекурсии. Внутри определения deepcopy_internal
следует использовать вместо deepcopy
, и переменная dict
должна обновляться соответствующим образом перед возвратом.
Base.getproperty
— Functiongetproperty(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{T <: Number}
x::T
end
julia> function Base.getproperty(obj::MyType, sym::Symbol)
if sym === :special
return obj.x + 1
else # fallback to getfield
return getfield(obj, sym)
end
end
julia> obj = MyType(1);
julia> obj.special
2
julia> obj.x
1
Следует переопределять getproperty
только в случае необходимости, так как это может быть запутанным, если поведение синтаксиса obj.f
необычно. Также обратите внимание, что использование методов часто предпочтительнее. См. также эту документацию по стилю для получения дополнительной информации: Предпочитайте экспортированные методы прямому доступу к полям.
См. также getfield
, propertynames
и setproperty!
.
Base.setproperty!
— Functionsetproperty!(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)
.
setproperty!
для модулей требует как минимум Julia 1.8.
См. также setfield!
, propertynames
и getproperty
.
Base.replaceproperty!
— Functionreplaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)
Выполните операцию сравнения и замены для x.f
с expected
на desired
, согласно принципу эгалитаризма. Синтаксис @atomicreplace x.f expected => desired
может быть использован вместо вызова функции.
Смотрите также replacefield!
setproperty!
, setpropertyonce!
.
Base.swapproperty!
— Functionswapproperty!(x, f::Symbol, v, order::Symbol=:not_atomic)
Синтаксис @atomic a.b, _ = c, a.b
возвращает (c, swapproperty!(a, :b, c, :sequentially_consistent))
, где должно быть одно выражение getproperty
, общее для обеих сторон.
См. также swapfield!
и setproperty!
.
Base.modifyproperty!
— Functionmodifyproperty!(x, f::Symbol, op, v, order::Symbol=:not_atomic)
Синтаксис @atomic op(x.f, v)
(и его эквивалент @atomic x.f op v
) возвращает modifyproperty!(x, :f, op, v, :sequentially_consistent)
, где первый аргумент должен быть выражением getproperty
и изменяется атомарно.
Вызов op(getproperty(x, f), v)
должен возвращать значение, которое по умолчанию может быть сохранено в поле f
объекта x
. В частности, в отличие от поведения по умолчанию setproperty!
, функция convert
не вызывается автоматически.
См. также modifyfield!
и setproperty!
.
Base.setpropertyonce!
— Functionsetpropertyonce!(x, f::Symbol, value, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)
Выполните операцию сравнения и замены для x.f
, чтобы установить его в value
, если он ранее не был установлен. Синтаксис @atomiconce x.f = value
может быть использован вместо вызова функции.
См. также setfieldonce!
, setproperty!
, replaceproperty!
.
Эта функция требует Julia 1.11 или более поздней версии.
Base.propertynames
— Functionpropertynames(x, private=false)
Получите кортеж или вектор свойств (x.property
) объекта x
. Это обычно то же самое, что и fieldnames(typeof(x))
, но типы, которые перегружают getproperty
, должны также перегружать propertynames
, чтобы получить свойства экземпляра типа.
propertynames(x)
может возвращать только "публичные" имена свойств, которые являются частью документированного интерфейса x
. Если вы хотите, чтобы он также возвращал "приватные" имена свойств, предназначенные для внутреннего использования, передайте true
в качестве второго необязательного аргумента. Завершение табуляции REPL по x.
показывает только свойства private=false
.
Смотрите также: hasproperty
, hasfield
.
Base.hasproperty
— Functionhasproperty(x, s::Symbol)
Возвращает булево значение, указывающее, имеет ли объект x
s
в качестве одного из своих собственных свойств.
Эта функция требует как минимум Julia 1.2.
Смотрите также: propertynames
, hasfield
.
Core.getfield
— Functiongetfield(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!
— Functionsetfield!(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.modifyfield!
— Functionmodifyfield!(value, name::Symbol, op, x, [order::Symbol]) -> Pair
modifyfield!(value, i::Int, op, x, [order::Symbol]) -> Pair
Атомарно выполняет операции получения и установки поля после применения функции op
.
y = getfield(value, name)
z = op(y, x)
setfield!(value, name, z)
return y => z
Если это поддерживается аппаратным обеспечением (например, атомарное увеличение), это может быть оптимизировано до соответствующей аппаратной инструкции, в противном случае будет использоваться цикл.
Эта функция требует Julia 1.7 или более поздней версии.
Core.replacefield!
— Functionreplacefield!(value, name::Symbol, expected, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)
replacefield!(value, i::Int, expected, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)
Атомарно выполнить операции для получения и условной установки поля на заданное значение.
y = getfield(value, name, fail_order)
ok = y === expected
if ok
setfield!(value, name, desired, success_order)
end
return (; old = y, success = ok)
Если это поддерживается аппаратным обеспечением, это может быть оптимизировано до соответствующей аппаратной инструкции, в противном случае будет использоваться цикл.
Эта функция требует Julia 1.7 или более поздней версии.
Core.swapfield!
— Functionswapfield!(value, name::Symbol, x, [order::Symbol])
swapfield!(value, i::Int, x, [order::Symbol])
Атомарно выполнить операции для одновременного получения и установки поля:
y = getfield(value, name)
setfield!(value, name, x)
return y
Эта функция требует Julia 1.7 или более поздней версии.
Core.setfieldonce!
— Functionsetfieldonce!(value, name::Union{Int,Symbol}, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool
Атомарно выполнить операции по установке поля в заданное значение, только если оно ранее не было установлено.
ok = !isdefined(value, name, fail_order)
if ok
setfield!(value, name, desired, success_order)
end
return ok
Эта функция требует Julia 1.11 или более поздней версии.
Core.isdefined
— Functionisdefined(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
Base.@isdefined
— Macro@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.convert
— Functionconvert(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
. Inf рассматривается как одно ulp больше, чем floatmax(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.promote
— Functionpromote(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.oftype
— Functionoftype(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.widen
— Functionwiden(x)
Если x
является типом, возвращает "больший" тип, определенный так, чтобы арифметические операции +
и -
гарантированно не переполняли и не теряли точность для любых комбинаций значений, которые может содержать тип x
.
Для целочисленных типов фиксированного размера менее 128 бит, widen
вернет тип с удвоенным количеством бит.
Если x
является значением, оно преобразуется в widen(typeof(x))
.
Примеры
julia> widen(Int32)
Int64
julia> widen(1.5f0)
1.5
Base.identity
— Functionidentity(x)
Функция идентичности. Возвращает свой аргумент.
Смотрите также: one
, oneunit
и I
из LinearAlgebra
.
Примеры
julia> identity("Well, what did you expect?")
"Well, what did you expect?"
Core.WeakRef
— TypeWeakRef(x)
w = WeakRef(x)
создает слабую ссылку на значение Julia x
: хотя w
содержит ссылку на x
, это не препятствует сборке мусора для x
. w.value
либо x
(если x
еще не был собран сборщиком мусора), либо nothing
(если x
был собран сборщиком мусора).
julia> x = "a string"
"a string"
julia> w = WeakRef(x)
WeakRef("a string")
julia> GC.gc()
julia> w # ссылка поддерживается через `x`
WeakRef("a string")
julia> x = nothing # очистить ссылку
julia> GC.gc()
julia> w
WeakRef(nothing)
Properties of Types
Type relations
Base.supertype
— Functionsupertype(T::DataType)
Возвращает суперкласс типа данных T
.
Примеры
julia> supertype(Int32)
Signed
Core.Type
— TypeCore.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.DataType
— TypeDataType <: 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.typejoin
— Functiontypejoin(T, S, ...)
Возвращает ближайшего общего предка типов T
и S
, т.е. самый узкий тип, от которого они оба наследуются. Рекурсивно обрабатывает дополнительные аргументы переменной длины.
Примеры
julia> typejoin(Int, Float64)
Real
julia> typejoin(Int, Float64, ComplexF32)
Number
Base.typeintersect
— Functiontypeintersect(T::Type, S::Type)
Вычисляет тип, который содержит пересечение T
и S
. Обычно это будет наименьший такой тип или один, близкий к нему.
Особый случай, когда гарантируется точное поведение: когда T <: S
, typeintersect(S, T) == T == typeintersect(T, S)
.
Base.promote_type
— Functionpromote_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_type
вызывает promote_rule
внутри для определения типа. Прямое перегружение promote_type
может вызвать ошибки неоднозначности.
```
Base.promote_rule
— Functionpromote_rule(type1, type2)
Указывает, какой тип должен использоваться функцией promote
при передаче значений типов type1
и type2
. Эта функция не должна вызываться напрямую, но к ней должны добавляться определения для новых типов по мере необходимости.
Base.promote_typejoin
— Functionpromote_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.isdispatchtuple
— Functionisdispatchtuple(T)
Определите, является ли тип T
"листовым типом" кортежа, что означает, что он может появляться в качестве сигнатуры типа в диспетчеризации и не имеет подтипов (или суперт типов), которые могут появляться в вызове. Если T
не является типом, верните false
.
Declared structure
Base.ismutable
— Functionismutable(v) -> Bool
Возвращает true
, если и только если значение v
изменяемо. См. Mutable Composite Types для обсуждения неизменяемости. Обратите внимание, что эта функция работает с значениями, поэтому, если вы передадите ей DataType
, она скажет вам, что значение этого типа изменяемо.
По техническим причинам ismutable
возвращает true
для значений определенных специальных типов (например, String
и Symbol
), хотя они не могут быть изменены допустимым образом.
См. также isbits
, isstructtype
.
Примеры
julia> ismutable(1)
false
julia> ismutable([1,2])
true
Эта функция требует как минимум Julia 1.5.
Base.isimmutable
— Functionisimmutable(v) -> Bool
Рассмотрите возможность использования !ismutable(v)
вместо этого, так как isimmutable(v)
будет заменен на !ismutable(v)
в будущем релизе. (С версии Julia 1.5)
Возвращает true
, если значение v
неизменно. См. Mutable Composite Types для обсуждения неизменности. Обратите внимание, что эта функция работает с значениями, поэтому, если вы передадите ей тип, она сообщит вам, что значение DataType
изменяемо.
Примеры
julia> isimmutable(1)
true
julia> isimmutable([1,2])
false
Base.ismutabletype
— Functionismutabletype(T) -> Bool
Определите, был ли тип T
объявлен как изменяемый тип (т.е. с использованием ключевого слова mutable struct
). Если T
не является типом, верните false
.
Эта функция требует как минимум Julia 1.7.
Base.isabstracttype
— Functionisabstracttype(T)
Определяет, был ли тип T
объявлен как абстрактный тип (т.е. с использованием синтаксиса abstract type
). Обратите внимание, что это не отрицание isconcretetype(T)
. Если T
не является типом, то возвращает false
.
Примеры
julia> isabstracttype(AbstractArray)
true
julia> isabstracttype(Vector)
false
Base.isprimitivetype
— Functionisprimitivetype(T) -> Bool
Определите, был ли тип T
объявлен как примитивный тип (т.е. с использованием синтаксиса primitive type
). Если T
не является типом, верните false
.
Base.issingletontype
— FunctionBase.issingletontype(T)
Определяет, имеет ли тип T
ровно один возможный экземпляр; например, структура типа без полей, кроме других одиночных значений. Если T
не является конкретным типом, то возвращает false
.
Base.isstructtype
— Functionisstructtype(T) -> Bool
Определите, был ли тип T
объявлен как тип структуры (т.е. с использованием ключевого слова struct
или mutable struct
). Если T
не является типом, верните false
.
Base.nameof
— Methodnameof(t::DataType) -> Symbol
Получите имя (возможно, обернутого в UnionAll
) DataType
(без его родительского модуля) в виде символа.
Примеры
julia> module Foo
struct S{T}
end
end
Foo
julia> nameof(Foo.S{T} where T)
:S
Base.fieldnames
— Functionfieldnames(x::DataType)
Получите кортеж с именами полей DataType
.
Смотрите также propertynames
, hasfield
.
Примеры
julia> fieldnames(Rational)
(:num, :den)
julia> fieldnames(typeof(1+im))
(:re, :im)
Base.fieldname
— Functionfieldname(x::DataType, i::Integer)
Получить имя поля i
типа DataType
.
Примеры
julia> fieldname(Rational, 1)
:num
julia> fieldname(Rational, 2)
:den
Core.fieldtype
— Functionfieldtype(T, name::Symbol | index::Int)
Определите объявленный тип поля (указанного по имени или индексу) в составном типе данных T
.
Примеры
julia> struct Foo
x::Int64
y::String
end
julia> fieldtype(Foo, :x)
Int64
julia> fieldtype(Foo, 2)
String
Base.fieldtypes
— Functionfieldtypes(T::Type)
Объявленные типы всех полей в составном типе данных T
в виде кортежа.
Эта функция требует как минимум Julia 1.1.
Примеры
julia> struct Foo
x::Int64
y::String
end
julia> fieldtypes(Foo)
(Int64, String)
Base.fieldcount
— Functionfieldcount(t::Type)
Получает количество полей, которые экземпляр данного типа будет иметь. Если тип слишком абстрактен для определения этого, будет выброшена ошибка.
Base.hasfield
— Functionhasfield(T::Type, name::Symbol)
Возвращает булево значение, указывающее, имеет ли T
name
в качестве одного из своих полей.
См. также fieldnames
, fieldcount
, hasproperty
.
Эта функция требует как минимум Julia 1.2.
Примеры
julia> struct Foo
bar::Int
end
julia> hasfield(Foo, :bar)
true
julia> hasfield(Foo, :x)
false
Core.nfields
— Functionnfields(x) -> Int
Получить количество полей в данном объекте.
Примеры
julia> a = 1//2;
julia> nfields(a)
2
julia> b = 1
1
julia> nfields(b)
0
julia> ex = ErrorException("Я сделал плохую вещь");
julia> nfields(ex)
1
В этих примерах a
является Rational
, который имеет два поля. b
является Int
, который является примитивным битовым типом без полей. ex
является ErrorException
, который имеет одно поле.
Base.isconst
— Functionisconst(m::Module, s::Symbol) -> Bool
Определяет, объявлена ли глобальная переменная как const
в данном модуле m
.
isconst(t::DataType, s::Union{Int,Symbol}) -> Bool
Определите, объявлено ли поле s
как const
в данном типе t
.
Base.isfieldatomic
— Functionisfieldatomic(t::DataType, s::Union{Int,Symbol}) -> Bool
Определяет, объявлено ли поле s
как @atomic
в данном типе t
.
Memory layout
Base.sizeof
— Methodsizeof(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: Абстрактный тип AbstractArray не имеет определенного размера.
Stacktrace:
[...]
Base.isconcretetype
— Functionisconcretetype(T)
Определяет, является ли тип T
конкретным типом, что означает, что он может иметь прямые экземпляры (значения x
, такие что typeof(x) === T
). Обратите внимание, что это не отрицание isabstracttype(T)
. Если T
не является типом, то возвращается false
.
Смотрите также: 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.isbits
— Functionisbits(x)
Возвращает true
, если x
является экземпляром типа isbitstype
.
Base.isbitstype
— Functionisbitstype(T)
Возвращает true
, если тип T
является "простым типом данных", что означает, что он неизменяемый и не содержит ссылок на другие значения, только примитивные
типы и другие типы isbitstype
. Типичными примерами являются числовые типы, такие как UInt8
, Float64
и Complex{Float64}
. Эта категория типов имеет значение, поскольку они действительны в качестве параметров типа, могут не отслеживать статус isdefined
/ isassigned
и имеют определённую компоновку, совместимую с C. Если T
не является типом, то возвращает false
.
См. также isbits
, isprimitivetype
, ismutable
.
Примеры
julia> isbitstype(Complex{Float64})
true
julia> isbitstype(Complex)
false
Base.fieldoffset
— Functionfieldoffset(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_alignment
— FunctionBase.datatype_alignment(dt::DataType) -> Int
Минимальное выравнивание выделения памяти для экземпляров этого типа. Может быть вызвано для любого isconcretetype
, хотя для Memory оно даст выравнивание элементов, а не всего объекта.
Base.datatype_haspadding
— FunctionBase.datatype_haspadding(dt::DataType) -> Bool
Возвращает, упакованы ли поля экземпляров этого типа в памяти, без промежуточных битов выравнивания (определяемых как биты, значение которых не влияет на тест на равенство, когда применяется к полям структуры). Может быть вызвано для любого isconcretetype
.
Base.datatype_pointerfree
— FunctionBase.datatype_pointerfree(dt::DataType) -> Bool
Возвращает, могут ли экземпляры этого типа содержать ссылки на память, управляемую сборщиком мусора. Может быть вызвано для любого isconcretetype
.
Special values
Base.typemin
— Functiontypemin(T)
Наименьшее значение, которое может быть представлено данным (действительным) числовым типом данных 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.typemax
— Functiontypemax(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.floatmin
— Functionfloatmin(T = Float64)
Возвращает наименьшее положительное нормальное число, представимое типом с плавающей запятой T
.
Примеры
julia> floatmin(Float16)
Float16(6.104e-5)
julia> floatmin(Float32)
1.1754944f-38
julia> floatmin()
2.2250738585072014e-308
Base.floatmax
— Functionfloatmax(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.maxintfloat
— Functionmaxintfloat(T=Float64)
Наибольшее последовательное число с плавающей запятой, представляющее целое значение, которое точно представлено в данном типе с плавающей запятой T
(по умолчанию Float64
).
То есть, maxintfloat
возвращает наименьшее положительное число с плавающей запятой, представляющее целое значение n
, такое что n+1
не может быть точно представлено в типе T
.
Когда требуется значение типа Integer
, используйте Integer(maxintfloat(T))
.
maxintfloat(T, S)
Наибольшее последовательное целое число, которое может быть представлено в данном типе с плавающей запятой T
и которое также не превышает максимальное целое число, представимое целым типом S
. Эквивалентно, это минимум maxintfloat(T)
и typemax(S)
.
Base.eps
— Methodeps(::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.eps
— Methodeps(x::AbstractFloat)
Возвращает единицу в последнем разряде (ulp) x
. Это расстояние между последовательными представимыми значениями с плавающей запятой при x
. В большинстве случаев, если расстояние с обеих сторон от x
различно, то берется большее из двух, то есть
eps(x) == max(x-prevfloat(x), nextfloat(x)-x)
Исключениями из этого правила являются наименьшие и наибольшие конечные значения (например, nextfloat(-Inf)
и prevfloat(Inf)
для Float64
), которые округляются до меньшего из значений.
Обоснование такого поведения заключается в том, что eps
ограничивает ошибку округления с плавающей запятой. При режиме округления по умолчанию RoundNearest
, если $y$ — это действительное число, а $x$ — ближайшее число с плавающей запятой к $y$, то
\[|y-x| \leq \operatorname{eps}(x)/2.\]
Смотрите также: 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.instances
— Functioninstances(T::Type)
Возвращает коллекцию всех экземпляров данного типа, если это применимо. В основном используется для перечисляемых типов (см. @enum
).
Примеры
julia> @enum Color red blue green
julia> instances(Color)
(red, blue, green)
Special Types
Core.Any
— TypeAny::DataType
Any
является объединением всех типов. У него есть определяющее свойство isa(x, Any) == true
для любого x
. Таким образом, Any
описывает всю вселенную возможных значений. Например, Integer
является подмножеством Any
, которое включает Int
, Int8
и другие целочисленные типы.
Core.Union
— TypeUnion{Types...}
Тип Union
является абстрактным типом, который включает все экземпляры любых из его аргументных типов. Это означает, что T <: Union{T,S}
и S <: Union{T,S}
.
Как и другие абстрактные типы, он не может быть инстанцирован, даже если все его аргументы не абстрактные.
Примеры
julia> IntOrString = Union{Int,AbstractString}
Union{Int64, AbstractString}
julia> 1 isa IntOrString # экземпляр Int включен в объединение
true
julia> "Hello!" isa IntOrString # String также включен
true
julia> 1.0 isa IntOrString # Float64 не включен, потому что он ни Int, ни AbstractString
false
Расширенная помощь
В отличие от большинства других параметрических типов, объединения являются ковариантными в своих параметрах. Например, Union{Real, String}
является подтипом Union{Number, AbstractString}
.
Пустое объединение Union{}
является нижним типом Julia.
Union{}
— KeywordUnion{}
Union{}
, пустой Union
типов, это тип, который не имеет значений. То есть, он имеет определяющее свойство isa(x, Union{}) == false
для любого x
. Base.Bottom
определяется как его псевдоним, а тип Union{}
— это Core.TypeofBottom
.
Примеры
julia> isa(nothing, Union{})
false
Core.UnionAll
— TypeUnionAll
Объединение типов по всем значениям параметра типа. UnionAll
используется для описания параметрических типов, где значения некоторых параметров неизвестны. См. раздел справки о UnionAll Types.
Примеры
julia> typeof(Vector)
UnionAll
julia> typeof(Vector{Int})
DataType
Core.Tuple
— TypeTuple{Types...}
Кортеж — это контейнер фиксированной длины, который может содержать любые значения разных типов, но не может быть изменен (он неизменяемый). Значения можно получить через индексацию. Литералы кортежей записываются с запятыми и скобками:
julia> (1, 1+1)
(1, 2)
julia> (1,)
(1,)
julia> x = (0.0, "hello", 6*7)
(0.0, "hello", 42)
julia> x[2]
"hello"
julia> typeof(x)
Tuple{Float64, String, Int64}
Кортеж длины 1 должен быть записан с запятой, (1,)
, так как (1)
будет просто скобочным значением. ()
представляет собой пустой (длиной 0) кортеж.
Кортеж можно построить из итератора, используя тип Tuple
в качестве конструктора:
julia> Tuple(["a", 1])
("a", 1)
julia> Tuple{String, Float64}(["a", 1])
("a", 1.0)
Типы кортежей являются ковариантными в своих параметрах: Tuple{Int}
является подтипом Tuple{Any}
. Поэтому Tuple{Any}
считается абстрактным типом, а типы кортежей являются конкретными только если их параметры таковыми являются. У кортежей нет имен полей; поля доступны только по индексу. Типы кортежей могут иметь любое количество параметров.
Смотрите раздел справочного руководства о Типах кортежей.
Смотрите также Vararg
, NTuple
, ntuple
, tuple
, NamedTuple
.
Core.NTuple
— TypeNTuple{N, T}
Компактный способ представления типа для кортежа длины N
, где все элементы имеют тип T
.
Примеры
julia> isa((1, 2, 3, 4, 5, 6), NTuple{6, Int})
true
Смотрите также ntuple
.
Core.NamedTuple
— TypeNamedTuple
NamedTuple
— это, как следует из названия, именованный Tuple
. То есть, это коллекция значений, похожая на кортеж, где каждый элемент имеет уникальное имя, представленное как Symbol
. Как и Tuple
, NamedTuple
неизменяемы; ни имена, ни значения не могут быть изменены на месте после создания.
Именованный кортеж можно создать как литерал кортежа с ключами, например, (a=1, b=2)
, или как литерал кортежа с точкой с запятой после открывающей скобки, например, (; a=1, b=2)
(эта форма также принимает программно сгенерированные имена, как описано ниже), или используя тип NamedTuple
в качестве конструктора, например, NamedTuple{(:a, :b)}((1,2))
.
Доступ к значению, связанному с именем в именованном кортеже, можно получить с помощью синтаксиса доступа к полям, например, 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
после точки с запятой внутри литерала кортежа. Этот синтаксис и синтаксис name=value
можно комбинировать:
julia> (; :a => 1, :b => 2, c=3)
(a = 1, b = 2, c = 3)
Пары имя-значение также можно предоставить, распаковывая именованный кортеж или любой итератор, который выдает коллекции из двух значений, где каждое значение является символом:
julia> keys = (:a, :b, :c); values = (1, 2, 3);
julia> NamedTuple{keys}(values)
(a = 1, b = 2, c = 3)
julia> (; (keys .=> values)...)
(a = 1, b = 2, c = 3)
julia> nt1 = (a=1, b=2);
julia> nt2 = (c=3, d=4);
julia> (; nt1..., nt2..., b=20) # финальное b перезаписывает значение из nt1
(a = 1, b = 20, c = 3, d = 4)
julia> (; zip(keys, values)...) # zip возвращает кортежи, такие как (:a, 1)
(a = 1, b = 2, c = 3)
Как и в именованных аргументах, идентификаторы и точечные выражения подразумевают имена:
julia> x = 0
0
julia> t = (; x)
(x = 0,)
julia> (; t.x)
(x = 0,)
Неявные имена из идентификаторов и точечных выражений доступны начиная с Julia 1.5.
Использование методов getindex
с несколькими Symbol
доступно начиная с Julia 1.7.
Base.@NamedTuple
— Macro@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
), но в остальном эквивалентна. Макрос NamedTuple
используется при выводе типов NamedTuple
, например, в REPL.
Например, кортеж (a=3.1, b="hello")
имеет тип NamedTuple{(:a, :b), Tuple{Float64, String}}
, который также можно объявить с помощью @NamedTuple
следующим образом:
julia> @NamedTuple{a::Float64, b::String}
@NamedTuple{a::Float64, b::String}
julia> @NamedTuple begin
a::Float64
b::String
end
@NamedTuple{a::Float64, b::String}
Этот макрос доступен начиная с Julia 1.5.
Base.@Kwargs
— Macro@Kwargs{key1::Type1, key2::Type2, ...}
Этот макрос предоставляет удобный способ для построения представления типа именованных аргументов с использованием той же синтаксической конструкции, что и @NamedTuple
. Например, когда у нас есть вызов функции, такой как func([позиционные аргументы]; kw1=1.0, kw2="2")
, мы можем использовать этот макрос для построения внутреннего представления типа именованных аргументов как @Kwargs{kw1::Float64, kw2::String}
. Синтаксис макроса специально разработан для упрощения типа сигнатуры метода с именованными аргументами, когда он выводится в представлении трассировки стека.
julia> @Kwargs{init::Int} # внутреннее представление именованных аргументов
Base.Pairs{Symbol, Int64, Tuple{Symbol}, @NamedTuple{init::Int64}}
julia> sum("julia"; init=1)
ERROR: MethodError: no method matching +(::Char, ::Char)
Функция `+` существует, но ни один метод не определен для этой комбинации типов аргументов.
Ближайшие кандидаты:
+(::Any, ::Any, ::Any, ::Any...)
@ Base operators.jl:585
+(::Integer, ::AbstractChar)
@ Base char.jl:247
+(::T, ::Integer) where T<:AbstractChar
@ Base char.jl:237
Трассировка стека:
[1] add_sum(x::Char, y::Char)
@ Base ./reduce.jl:24
[2] BottomRF
@ Base ./reduce.jl:86 [inlined]
[3] _foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, init::Int64, itr::String)
@ Base ./reduce.jl:62
[4] foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, nt::Int64, itr::String)
@ Base ./reduce.jl:48 [inlined]
[5] mapfoldl_impl(f::typeof(identity), op::typeof(Base.add_sum), nt::Int64, itr::String)
@ Base ./reduce.jl:44 [inlined]
[6] mapfoldl(f::typeof(identity), op::typeof(Base.add_sum), itr::String; init::Int64)
@ Base ./reduce.jl:175 [inlined]
[7] mapreduce(f::typeof(identity), op::typeof(Base.add_sum), itr::String; kw::@Kwargs{init::Int64})
@ Base ./reduce.jl:307 [inlined]
[8] sum(f::typeof(identity), a::String; kw::@Kwargs{init::Int64})
@ Base ./reduce.jl:535 [inlined]
[9] sum(a::String; kw::@Kwargs{init::Int64})
@ Base ./reduce.jl:564 [inlined]
[10] top-level scope
@ REPL[12]:1
Этот макрос доступен начиная с Julia 1.10.
Base.Val
— TypeVal(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.Vararg
— ConstantVararg{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.Nothing
— TypeBase.isnothing
— Functionisnothing(x)
Возвращает true
, если x === nothing
, и возвращает false
, если нет.
Эта функция требует как минимум Julia 1.1.
Смотрите также something
, Base.notnothing
, ismissing
.
Base.notnothing
— Functionnotnothing(x)
Выдайте ошибку, если x === nothing
, и верните x
, если это не так.
Base.Some
— TypeSome{T}
Обертка типа, используемая в Union{Some{T}, Nothing}
для различения отсутствия значения (nothing
) и наличия значения nothing
(т.е. Some(nothing)
).
Используйте something
для доступа к значению, обернутому объектом Some
.
Base.something
— Functionчто-то(x...)
Вернуть первое значение в аргументах, которое не равно nothing
, если такое есть. В противном случае выбросить ошибку. Аргументы типа Some
распаковываются.
См. также coalesce
, skipmissing
, @something
.
Примеры
julia> что-то(nothing, 1)
1
julia> что-то(Some(1), nothing)
1
julia> что-то(Some(nothing), 2) === nothing
true
julia> что-то(missing, nothing)
missing
julia> что-то(nothing, nothing)
ERROR: ArgumentError: Нет значений аргументов
Base.@something
— Macro@something(x...)
Краткая версия something
.
Примеры
julia> f(x) = (println("f($x)"); nothing);
julia> a = 1;
julia> a = @something a f(2) f(3) error("Не удалось найти значение по умолчанию для `a`")
1
julia> b = nothing;
julia> b = @something b f(2) f(3) error("Не удалось найти значение по умолчанию для `b`")
f(2)
f(3)
ERROR: Не удалось найти значение по умолчанию для `b`
[...]
julia> b = @something b f(2) f(3) Some(nothing)
f(2)
f(3)
julia> b === nothing
true
Этот макрос доступен начиная с Julia 1.7.
Base.Enums.Enum
— TypeEnum{T<:Integer}
Абстрактный суперкласс всех перечисляемых типов, определенных с помощью @enum
.
Base.Enums.@enum
— Macro@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) = "Я фрукт со значением: $(Int(x))"
f (generic function with 1 method)
julia> f(apple)
"Я фрукт со значением: 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.Expr
— TypeExpr(head::Symbol, args...)
Тип, представляющий составные выражения в разобранном коде julia (AST). Каждое выражение состоит из head
Symbol
, который определяет, какой тип выражения это (например, вызов, цикл for, условное выражение и т.д.), и подвыражений (например, аргументы вызова). Подвыражения хранятся в поле Vector{Any}
с именем args
.
Смотрите главу руководства по Метапрограммированию и документацию для разработчиков Julia ASTs.
Примеры
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.Symbol
— TypeСимвол
Тип объекта, используемого для представления идентификаторов в разобранном коде julia (AST). Также часто используется как имя или метка для идентификации сущности (например, в качестве ключа словаря). Symbol
s можно вводить с помощью оператора кавычек :
:
julia> :name
:name
julia> typeof(:name)
Symbol
julia> x = 42
42
julia> eval(:x)
42
Symbol
s также можно создавать из строк или других значений, вызывая конструктор Symbol(x...)
.
Symbol
s неизменяемы, и их реализация повторно использует один и тот же объект для всех Symbol
s с одинаковым именем.
В отличие от строк, Symbol
s являются "атомными" или "скалярными" сущностями, которые не поддерживают итерацию по символам.
Core.Symbol
— MethodSymbol(x...) -> Symbol
Создайте Symbol
, объединяя строковые представления аргументов вместе.
Примеры
julia> Symbol("my", "name")
:myname
julia> Symbol("day", 4)
:day4
Core.Module
— TypeМодуль
Модуль
— это отдельное пространство глобальных переменных. См. module
и раздел руководства о модулях для получения подробной информации.
Module(name::Symbol=:anonymous, std_imports=true, default_names=true)
Возвращает модуль с указанным именем. baremodule
соответствует Module(:ModuleName, false)
Пустой модуль, не содержащий никаких имен, можно создать с помощью Module(:ModuleName, false, false)
. Этот модуль не будет импортировать Base
или Core
и не содержит ссылки на себя.
Generic Functions
Core.Function
— TypeФункция
Абстрактный тип всех функций.
Примеры
julia> isa(+, Function)
true
julia> typeof(sin)
typeof(sin) (единственный тип функции sin, подтип Function)
julia> ans <: Function
true
Base.hasmethod
— Functionhasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool
Определяет, имеет ли данная обобщенная функция метод, соответствующий данному Tuple
типов аргументов с верхней границей возраста мира, заданной world
.
Если предоставлен кортеж имен именованных аргументов kwnames
, это также проверяет, имеет ли метод f
, соответствующий t
, указанные имена именованных аргументов. Если соответствующий метод принимает переменное количество именованных аргументов, например, с kwargs...
, любые имена, указанные в kwnames
, считаются допустимыми. В противном случае предоставленные имена должны быть подмножеством именованных аргументов метода.
См. также applicable
.
Предоставление имен именованных аргументов требует 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 принимает произвольные kwargs
true
Core.applicable
— Functionapplicable(f, args...) -> Bool
Определите, имеет ли данная обобщенная функция метод, применимый к данным аргументам.
Смотрите также hasmethod
.
Примеры
julia> function f(x, y)
x + y
end;
julia> applicable(f, 1)
false
julia> applicable(f, 1, 2)
true
Base.isambiguous
— FunctionBase.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.invoke
— Functioninvoke(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.@invoke
— Macro@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
.
Он также поддерживает следующий синтаксис:
@invoke (x::X).f
расширяется доinvoke(getproperty, Tuple{X,Symbol}, x, :f)
@invoke (x::X).f = v::V
расширяется доinvoke(setproperty!, Tuple{X,Symbol,V}, x, :f, v)
@invoke (xs::Xs)[i::I]
расширяется доinvoke(getindex, Tuple{Xs,I}, xs, i)
@invoke (xs::Xs)[i::I] = v::V
расширяется доinvoke(setindex!, Tuple{Xs,V,I}, xs, v, i)
Примеры
julia> @macroexpand @invoke f(x::T, y)
:(Core.invoke(f, Tuple{T, Core.Typeof(y)}, x, y))
julia> @invoke 420::Integer % Unsigned
0x00000000000001a4
julia> @macroexpand @invoke (x::X).f
:(Core.invoke(Base.getproperty, Tuple{X, Core.Typeof(:f)}, x, :f))
julia> @macroexpand @invoke (x::X).f = v::V
:(Core.invoke(Base.setproperty!, Tuple{X, Core.Typeof(:f), V}, x, :f, v))
julia> @macroexpand @invoke (xs::Xs)[i::I]
:(Core.invoke(Base.getindex, Tuple{Xs, I}, xs, i))
julia> @macroexpand @invoke (xs::Xs)[i::I] = v::V
:(Core.invoke(Base.setindex!, Tuple{Xs, V, I}, xs, v, i))
Этот макрос требует Julia 1.7 или новее.
Этот макрос экспортируется начиная с Julia 1.9.
Дополнительный синтаксис поддерживается начиная с Julia 1.10.
Base.invokelatest
— Functioninvokelatest(f, args...; kwargs...)
Вызывает f(args...; kwargs...)
, но гарантирует, что будет выполнен самый последний метод f
. Это полезно в специализированных обстоятельствах, например, в долгих циклах событий или функциях обратного вызова, которые могут вызывать устаревшие версии функции f
. (Недостаток в том, что invokelatest
несколько медленнее, чем прямой вызов f
, и тип результата не может быть выведен компилятором.)
До Julia 1.9 эта функция не экспортировалась и вызывалась как Base.invokelatest
.
Base.@invokelatest
— Macro@invokelatest f(args...; kwargs...)
Предоставляет удобный способ вызова invokelatest
. @invokelatest f(args...; kwargs...)
просто будет развернуто в Base.invokelatest(f, args...; kwargs...)
.
Он также поддерживает следующий синтаксис:
@invokelatest x.f
разворачивается вBase.invokelatest(getproperty, x, :f)
@invokelatest x.f = v
разворачивается вBase.invokelatest(setproperty!, x, :f, v)
@invokelatest xs[i]
разворачивается вBase.invokelatest(getindex, xs, i)
@invokelatest xs[i] = v
разворачивается вBase.invokelatest(setindex!, xs, v, i)
julia> @macroexpand @invokelatest f(x; kw=kwv)
:(Base.invokelatest(f, x; kw = kwv))
julia> @macroexpand @invokelatest x.f
:(Base.invokelatest(Base.getproperty, x, :f))
julia> @macroexpand @invokelatest x.f = v
:(Base.invokelatest(Base.setproperty!, x, :f, v))
julia> @macroexpand @invokelatest xs[i]
:(Base.invokelatest(Base.getindex, xs, i))
julia> @macroexpand @invokelatest xs[i] = v
:(Base.invokelatest(Base.setindex!, xs, v, i))
Этот макрос требует Julia 1.7 или новее.
До Julia 1.9 этот макрос не экспортировался и вызывался как Base.@invokelatest
.
Дополнительный синтаксис x.f
и xs[i]
требует Julia 1.10.
new
— Keywordnew, 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.:∘
— Functionf ∘ g
Составление функций: т.е. (f ∘ g)(args...; kwargs...)
означает f(g(args...; kwargs...))
. Символ ∘
можно ввести в Julia REPL (и в большинстве редакторов, правильно настроенных) набрав \circ<tab>
.
Составление функций также работает в префиксной форме: ∘(f, g)
то же самое, что и f ∘ g
. Префиксная форма поддерживает составление нескольких функций: ∘(f, g, h) = f ∘ g ∘ h
и распаковку ∘(fs...)
для составления итерируемой коллекции функций. Последний аргумент для ∘
выполняется первым.
Составление нескольких функций требует как минимум Julia 1.4.
Составление одной функции ∘(f) требует как минимум Julia 1.5.
Использование именованных аргументов требует как минимум Julia 1.7.
Примеры
julia> map(uppercase∘first, ["apple", "banana", "carrot"])
3-element Vector{Char}:
'A': ASCII/Unicode U+0041 (категория Lu: Буква, заглавная)
'B': ASCII/Unicode U+0042 (категория Lu: Буква, заглавная)
'C': ASCII/Unicode U+0043 (категория Lu: Буква, заглавная)
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.ComposedFunction
— TypeComposedFunction{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
ComposedFunction требует как минимум Julia 1.6. В более ранних версиях ∘
возвращает анонимную функцию вместо этого.
См. также ∘
.
Base.splat
— Functionsplat(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.Fix1
— TypeFix1(f, x)
Тип, представляющий частично применённую версию функции с двумя аргументами f
, с первым аргументом, зафиксированным на значении "x". Другими словами, Fix1(f, x)
ведёт себя аналогично y->f(x, y)
.
См. также Fix2
.
Base.Fix2
— TypeFix2(f, x)
Тип, представляющий частично применённую версию функции с двумя аргументами f
, где второй аргумент зафиксирован на значении "x". Другими словами, Fix2(f, x)
ведёт себя аналогично y->f(y, x)
.
Syntax
Core.eval
— FunctionCore.eval(m::Module, expr)
Оцените выражение в данном модуле и верните результат.
eval
— Functioneval(expr)
Оцените выражение в глобальной области видимости содержащего модуля. Каждый Module
(за исключением тех, которые определены с помощью baremodule
) имеет свое собственное определение eval
с одним аргументом, которое оценивает выражения в этом модуле.
Base.@eval
— Macro@eval [mod,] ex
Оцените выражение с интерполированными значениями, используя eval
. Если предоставлены два аргумента, первый - это модуль, в котором нужно выполнить оценку.
Base.evalfile
— Functionevalfile(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.esc
— Functionesc(e)
Действителен только в контексте Expr
, возвращаемого макросом. Предотвращает прохождение гигиенического макроса, превращающее встроенные переменные в переменные gensym. См. раздел Macros главы о метапрограммировании в руководстве для получения дополнительных сведений и примеров.
Base.@inbounds
— Macro@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)
в функции, подобной приведенной выше, не является безопасным в пределах границ, поскольку первый индекс A
может не быть 1
для всех пользовательских типов, которые являются подтипами AbstractArray
.
Base.@boundscheck
— Macro@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: попытка доступа к 2-элементному UnitRange{Int64} по индексу [-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_inbounds
— Macro@propagate_inbounds
Сообщает компилятору инлайнить функцию, сохраняя контекст inbounds вызывающего.
Base.@inline
— Macro@inline
Дайте компилятору подсказку, что эту функцию стоит встроить.
Малые функции обычно не нуждаются в аннотации @inline
, так как компилятор делает это автоматически. Используя @inline
для больших функций, можно дать компилятору дополнительный толчок для их встраивания.
@inline
можно применять сразу перед определением функции или внутри тела функции.
# аннотировать длинное определение
@inline function longdef(x)
...
end
# аннотировать короткое определение
@inline shortdef(x) = ...
# аннотировать анонимную функцию, которую создает блок `do`
f() do
@inline
...
end
Использование внутри тела функции требует как минимум 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
Когда есть вложенные аннотации точки вызова, самая внутренняя аннотация имеет приоритет:
@noinline let a0, b0 = ...
a = @inline f(a0) # компилятор попытается встроить этот вызов
b = f(b0) # компилятор НЕ попытается встроить этот вызов
return a, b
end
Хотя аннотация точки вызова попытается принудительно встроить, независимо от модели затрат, все же есть шансы, что это не удастся. Особенно, рекурсивные вызовы не могут быть встроены, даже если они аннотированы как @inline
.
Аннотация точки вызова требует как минимум Julia 1.8.
Base.@noinline
— Macro@noinline
Дайте компилятору подсказку, что он не должен инлайнить функцию.
Маленькие функции обычно инлайнятся автоматически. Используя @noinline
для маленьких функций, можно предотвратить автоматическое инлайнинг.
@noinline
можно применить сразу перед определением функции или внутри тела функции.
# аннотировать длинное определение
@noinline function longdef(x)
...
end
# аннотировать короткое определение
@noinline shortdef(x) = ...
# аннотировать анонимную функцию, которую создает блок `do`
f() do
@noinline
...
end
Использование внутри тела функции требует как минимум 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
Когда есть вложенные аннотации точки вызова, самая внутренняя аннотация имеет приоритет:
@inline let a0, b0 = ...
a = @noinline f(a0) # компилятор НЕ попытается инлайнить этот вызов
b = f(b0) # компилятор попытается инлайнить этот вызов
return a, b
end
Аннотация точки вызова требует как минимум Julia 1.8.
Если функция тривиальна (например, возвращает константу), она может быть инлайнена в любом случае.
Base.@nospecialize
— Macro@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
влияет на генерацию кода, но не на вывод типов: он ограничивает разнообразие результирующего нативного кода, но не накладывает никаких ограничений (кроме стандартных) на вывод типов. Используйте Base.@nospecializeinfer
вместе с @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.@specialize
— Macro@specialize
Сбросить подсказку специализации для аргумента обратно к значению по умолчанию. Для получения подробной информации смотрите @nospecialize
.
Base.@nospecializeinfer
— MacroBase.@nospecializeinfer function f(args...)
@nospecialize ...
...
end
Base.@nospecializeinfer f(@nospecialize args...) = ...
Сообщает компилятору, чтобы он выводил f
, используя объявленные типы аргументов с @nospecialize
. Это можно использовать для ограничения количества специализирований, сгенерированных компилятором во время вывода.
Примеры
julia> f(A::AbstractArray) = g(A)
f (generic function with 1 method)
julia> @noinline Base.@nospecializeinfer 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)::Any
└── return %1
) => Any
В этом примере f
будет выведен для каждого конкретного типа A
, но g
будет выведен только один раз с объявленным типом аргумента A::AbstractArray
, что означает, что компилятор, вероятно, не увидит чрезмерное время вывода на него, в то время как он не может вывести конкретный возвращаемый тип. Без @nospecializeinfer
, f([1.0])
вывел бы возвращаемый тип g
как Float64
, указывая на то, что вывод выполнялся для g(::Vector{Float64})
, несмотря на запрет на специализированную генерацию кода.
Использование Base.@nospecializeinfer
требует версию Julia 1.10.
Base.@constprop
— MacroBase.@constprop настройка [ex]
Управляйте режимом межпроцедурного постоянного распространения для аннотированной функции.
Поддерживаются два настройки
:
Base.@constprop :aggressive [ex]
: применяйте постоянное распространение агрессивно. Для метода, где возвращаемый тип зависит от значения аргументов, это может привести к улучшению результатов вывода типов за счет дополнительного времени компиляции.Base.@constprop :none [ex]
: отключите постоянное распространение. Это может сократить время компиляции для функций, которые Julia в противном случае могла бы считать достойными постоянного распространения. Общие случаи - это функции с аргументами типаBool
илиSymbol
или с именованными аргументами.
Base.@constprop
может быть применен сразу перед определением функции или внутри тела функции.
# аннотировать длинное определение
Base.@constprop :aggressive function longdef(x)
...
end
# аннотировать короткое определение
Base.@constprop :aggressive shortdef(x) = ...
# аннотировать анонимную функцию, которую создает блок `do`
f() do
Base.@constprop :aggressive
...
end
Использование внутри тела функции требует как минимум Julia 1.10.
Base.gensym
— Functiongensym([tag])
Генерирует символ, который не будет конфликтовать с другими именами переменных (в том же модуле).
Base.@gensym
— Macro@gensym
Генерирует символ gensym для переменной. Например, @gensym x y
преобразуется в x = gensym("x"); y = gensym("y")
.
var"name"
— Keywordvar
Синтаксис var"#example#"
относится к переменной с именем Symbol("#example#")
, даже если #example#
не является допустимым именем идентификатора в Julia.
Это может быть полезно для взаимодействия с языками программирования, которые имеют разные правила для построения допустимых идентификаторов. Например, чтобы сослаться на переменную R
draw.segments
, вы можете использовать var"draw.segments"
в вашем коде на Julia.
Он также используется для show
исходного кода julia, который прошел через макро-гигиену или иначе содержит имена переменных, которые не могут быть нормально разобраны.
Обратите внимание, что этот синтаксис требует поддержки парсера, поэтому он расширяется непосредственно парсером, а не реализуется как обычный строковый макрос @var_str
.
Этот синтаксис требует как минимум Julia 1.3.
Base.@goto
— Macro@goto name
@goto name
безусловно переходит к оператору в месте @label name
.
@label
и @goto
не могут создавать переходы к различным верхнеуровневым операторам. Попытки вызвать ошибку. Чтобы все же использовать @goto
, заключите @label
и @goto
в блок.
Base.@label
— Macro@label name
Помечает утверждение символической меткой name
. Метка обозначает конечную точку безусловного перехода с помощью @goto name
.
Base.SimdLoop.@simd
— Macro@simd
Аннотируйте цикл for
, чтобы позволить компилятору принимать дополнительные свободы для разрешения переупорядочивания циклов.
Эта функция является экспериментальной и может измениться или исчезнуть в будущих версиях Julia. Неправильное использование макроса @simd
может привести к неожиданным результатам.
Объект, по которому происходит итерация в цикле @simd for
, должен быть одномерным диапазоном. Используя @simd
, вы утверждаете несколько свойств цикла:
- Безопасно выполнять итерации в произвольном или перекрывающемся порядке, с особым вниманием к переменным редукции.
- Операции с плавающей запятой над переменными редукции могут быть переупорядочены или сокращены, что может привести к другим результатам, чем без
@simd
.
Во многих случаях Julia может автоматически векторизовать внутренние циклы for
без использования @simd
. Использование @simd
дает компилятору немного больше свободы, чтобы сделать это возможным в большем количестве ситуаций. В любом случае, ваш внутренний цикл должен иметь следующие свойства, чтобы разрешить векторизацию:
- Цикл должен быть самым внутренним циклом.
- Тело цикла должно содержать линейный код. Поэтому
@inbounds
в настоящее время необходимо для всех обращений к массивам. Компилятор иногда может преобразовать короткие выражения&&
,||
и?:
в линейный код, если безопасно оценивать все операнды без условий. Рассмотрите возможность использования функцииifelse
вместо?:
в цикле, если это безопасно. - Обращения должны иметь шаблон шага и не могут быть "сборками" (чтения с произвольными индексами) или "разбросами" (записи с произвольными индексами).
- Шаг должен быть единичным.
@simd
по умолчанию не утверждает, что цикл полностью свободен от зависимостей памяти, переносимых по циклу, что является предположением, которое легко может быть нарушено в обобщенном коде. Если вы пишете не обобщенный код, вы можете использовать @simd ivdep for ... end
, чтобы также утверждать, что:
- Не существует зависимостей памяти, переносимых по циклу.
- Ни одна итерация никогда не ждет завершения предыдущей итерации для продвижения вперед.
Base.@polly
— Macro@polly
Сообщает компилятору применить полиэдральный оптимизатор Polly к функции.
Base.@generated
— Macro@generated f
@generated
используется для аннотирования функции, которая будет сгенерирована. В теле сгенерированной функции можно читать только типы аргументов (не значения). Функция возвращает цитируемое выражение, которое оценивается при вызове функции. Макрос @generated
не следует использовать для функций, изменяющих глобальную область видимости или зависящих от изменяемых элементов.
Смотрите Metaprogramming для получения дополнительных сведений.
Примеры
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.@assume_effects
— MacroBase.@assume_effects настройка... [ex]
Переопределите моделирование эффектов компилятора. Этот макрос можно использовать в нескольких контекстах:
- Непосредственно перед определением метода, чтобы переопределить все моделирование эффектов примененного метода.
- Внутри тела функции без каких-либо аргументов, чтобы переопределить все моделирование эффектов окружающего метода.
- Применяется к блоку кода, чтобы переопределить локальное моделирование эффектов примененного блока кода.
Примеры
julia> Base.@assume_effects :terminates_locally function fact(x)
# использование 1:
# этот :terminates_locally позволяет `fact` быть константно сложенным
res = 1
0 ≤ x < 20 || error("плохой факт")
while x > 1
res *= x
x -= 1
end
return res
end
fact (generic function with 1 method)
julia> code_typed() do
fact(12)
end |> only
CodeInfo(
1 ─ return 479001600
) => Int64
julia> code_typed() do
map((2,3,4)) do x
# использование 2:
# этот :terminates_locally позволяет этой анонимной функции быть константно сложенной
Base.@assume_effects :terminates_locally
res = 1
0 ≤ x < 20 || error("плохой факт")
while x > 1
res *= x
x -= 1
end
return res
end
end |> only
CodeInfo(
1 ─ return (2, 6, 24)
) => Tuple{Int64, Int64, Int64}
julia> code_typed() do
map((2,3,4)) do x
res = 1
0 ≤ x < 20 || error("плохой факт")
# использование 3:
# с этой аннотацией :terminates_locally компилятор пропускает порчу
# эффекта `:terminates` внутри этого блока `while`, позволяя родительской
# анонимной функции быть константно сложенной
Base.@assume_effects :terminates_locally while x > 1
res *= x
x -= 1
end
return res
end
end |> only
CodeInfo(
1 ─ return (2, 6, 24)
) => Tuple{Int64, Int64, Int64}
Использование Base.@assume_effects
требует версию Julia 1.8.
Использование внутри тела функции требует как минимум Julia 1.10.
Аннотация блока кода требует как минимум Julia 1.11.
Неправильное использование этого макроса вызывает неопределенное поведение (включая сбои, неправильные ответы или другие трудно отслеживаемые ошибки). Используйте с осторожностью и только в крайнем случае, если это абсолютно необходимо. Даже в таком случае вы ДОЛЖНЫ предпринять все возможные шаги, чтобы минимизировать силу утверждения эффекта (например, не используйте :total
, если :nothrow
было бы достаточно).
В общем, каждое значение setting
делает утверждение о поведении функции, не требуя от компилятора доказательства того, что это поведение действительно истинно. Эти утверждения делаются для всех мировых эпох. Поэтому рекомендуется ограничить использование общих функций, которые могут быть позже расширены, чтобы опровергнуть предположение (что вызвало бы неопределенное поведение).
Поддерживаются следующие setting
:
:consistent
:effect_free
:nothrow
:terminates_globally
:terminates_locally
:notaskstate
:inaccessiblememonly
:noub
:noub_if_noinbounds
:nortcall
:foldable
:removable
:total
Расширенная помощь
:consistent
Настройка :consistent
утверждает, что для равных (===
) входных данных:
- Способ завершения (возвращаемое значение, исключение, не завершение) всегда будет одинаковым.
- Если метод возвращает, результаты всегда будут равны.
Это в частности подразумевает, что метод не должен возвращать только что выделенный изменяемый объект. Множественные выделения изменяемых объектов (даже с идентичным содержимым) не равны.
Утверждение :consistent
делается по всем мировым эпохам. Формально, пусть $fᵢ$ — это оценка $f$ в мировой эпохе $i$, тогда эта настройка требует:
\[∀ i, x, y: x ≡ y → fᵢ(x) ≡ fᵢ(y)\]
Однако для двух мировых эпох $i$, $j$ так, что $i ≠ j$, мы можем иметь $fᵢ(x) ≢ fⱼ(y)$.
Дальнейшее следствие заключается в том, что функции :consistent
не могут зависеть от состояния кучи или любого другого глобального состояния, которое не является постоянным для данной мировой эпохи.
Утверждение :consistent
включает все законные переписывания, выполняемые оптимизатором. Например, операции с плавающей точкой fastmath не считаются :consistent
, потому что оптимизатор может переписать их, что приводит к тому, что вывод не будет :consistent
, даже для одной и той же мировой эпохи (например, потому что один выполнялся в интерпретаторе, в то время как другой был оптимизирован).
Если функции :consistent
завершаются выбрасыванием исключения, само это исключение не требуется соответствовать требованию равенства, указанному выше.
:effect_free
Настройка :effect_free
утверждает, что метод свободен от внешне семантически видимых побочных эффектов. Следующий список является неполным списком внешне семантически видимых побочных эффектов:
- Изменение значения глобальной переменной.
- Мутация кучи (например, массива или изменяемого значения), за исключением указанных ниже
- Изменение таблицы методов (например, через вызовы eval)
- Файловый/сетевой и т.д. ввод-вывод
- Переключение задач
Однако следующие эффекты явно не являются семантически видимыми, даже если они могут быть наблюдаемыми:
- Выделения памяти (как изменяемой, так и неизменяемой)
- Прошедшее время
- Сборка мусора
- Мутации кучи объектов, срок службы которых не превышает метод (т.е. были выделены в методе и не выходят за его пределы).
- Возвращаемое значение (которое внешне видно, но не является побочным эффектом)
Общее правило здесь заключается в том, что внешне видимый побочный эффект — это все, что повлияло бы на выполнение остальной части программы, если бы функция не была выполнена.
Утверждение :effect_free
делается как для самого метода, так и для любого кода, который выполняется методом. Имейте в виду, что утверждение должно быть действительным для всех мировых эпох и соответственно ограничить использование этого утверждения.
:nothrow
Настройка :nothrow
утверждает, что этот метод не выбрасывает исключение (т.е. либо всегда возвращает значение, либо никогда не возвращает).
Разрешается, чтобы методы с аннотацией :nothrow
использовали обработку исключений внутри, при условии, что исключение не выбрасывается из самого метода.
Если выполнение метода может вызвать MethodError
и подобные исключения, то метод не считается :nothrow
. Однако обратите внимание, что ошибки, зависящие от окружения, такие как StackOverflowError
или InterruptException
, не моделируются этим эффектом, и, следовательно, метод, который может привести к StackOverflowError
, не обязательно должен быть !:nothrow
(хотя обычно он также должен быть !:terminates
).
: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
охватывает любые другие методы, вызываемые аннотированным методом.
:noub
Настройка :noub
утверждает, что метод не будет выполнять никакого неопределенного поведения (для любого ввода). Обратите внимание, что неопределенное поведение может технически привести к тому, что метод нарушит любые другие утверждения эффекта (такие как :consistent
или :effect_free
), но мы это не моделируем, и они предполагают отсутствие неопределенного поведения.
:nortcall
Настройка :nortcall
утверждает, что метод не вызывает Core.Compiler.return_type
, и что любые другие методы, которые этот метод может вызывать, также не вызывают Core.Compiler.return_type
.
Чтобы быть точным, это утверждение может быть использовано, когда вызов Core.Compiler.return_type
не выполняется во время выполнения; то есть, когда результат Core.Compiler.return_type
известен точно во время компиляции, и вызов устраняется оптимизатором. Однако, поскольку то, будет ли результат Core.Compiler.return_type
сложен во время компиляции, сильно зависит от реализации компилятора, обычно рискованно утверждать это, если рассматриваемый метод использует Core.Compiler.return_type
в какой-либо форме.
:foldable
Эта настройка является удобным ярлыком для набора эффектов, которые компилятор требует, чтобы гарантировать константное сложение вызова во время компиляции. В настоящее время она эквивалентна следующим setting
:
:consistent
:effect_free
:terminates_globally
:noub
:nortcall
Этот список в частности не включает :nothrow
. Компилятор все равно будет пытаться выполнить константное распространение и отмечать любые выброшенные ошибки во время компиляции. Обратите внимание, однако, что в соответствии с требованиями :consistent
, любой такой аннотированный вызов должен последовательно выбрасывать, учитывая одни и те же значения аргументов.
Явная аннотация @inbounds
внутри функции также отключит константное сложение и не будет переопределена :foldable
.
:removable
Эта настройка является удобным ярлыком для набора эффектов, которые компилятор требует, чтобы гарантировать удаление вызова, результат которого не используется во время компиляции. В настоящее время она эквивалентна следующим setting
:
:effect_free
:nothrow
:terminates_globally
:total
Эта настройка является максимальным возможным набором эффектов. В настоящее время она подразумевает следующие другие setting
:
:consistent
:effect_free
:nothrow
:terminates_globally
:notaskstate
:inaccessiblememonly
:noub
:nortcall
:total
является очень сильным утверждением и, вероятно, получит дополнительные семантики в будущих версиях Julia (например, если будут добавлены дополнительные эффекты и включены в определение :total
). В результате его следует использовать с осторожностью. Когда это возможно, предпочтительнее использовать минимально возможный набор конкретных утверждений эффекта, необходимых для конкретного применения. В случаях, когда к набору функций применимо большое количество переопределений эффекта, рекомендуется использовать пользовательский макрос вместо использования :total
.
Отрицательные эффекты
Имена эффектов могут быть предварены !
, чтобы указать, что эффект должен быть удален из ранее указанного метаэффекта. Например, :total !:nothrow
указывает, что хотя вызов в целом является полным, он может, однако, выбросить.
Managing deprecations
Base.@deprecate
— Macro@deprecate old new [export_old=true]
Устаревший метод old
и укажите замену new
, определяя новый метод old
с указанной сигнатурой в процессе.
Чтобы предотвратить экспорт old
, установите export_old
в false
.
Смотрите также Base.depwarn()
.
Начиная с 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. Для более ранних версий вы можете вручную передавать позиционные и ключевые аргументы, сделав @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 method for generic function "old" from Main:
[1] old(x::Int64)
@ deprecated.jl:94
определит и устарит метод old(x::Int)
, который зеркалит new(x::Int)
, но не определит и не устарит метод old(x::Float64)
.
Base.depwarn
— FunctionBase.depwarn(msg::String, funcsym::Symbol; force=false)
Выводит msg
как предупреждение о устаревании. Символ funcsym
должен быть именем вызывающей функции, который используется для обеспечения того, чтобы предупреждение о устаревании выводилось только в первый раз для каждого места вызова. Установите force=true
, чтобы принудительно показывать предупреждение всегда, даже если Julia была запущена с --depwarn=no
(по умолчанию).
Смотрите также @deprecate
.
Примеры
function deprecated_func()
Base.depwarn("Не используйте `deprecated_func()`!", :deprecated_func)
1 + 1
end
Missing Values
Base.Missing
— TypeПропущено
Тип без полей, единственный экземпляр которого missing
используется для представления пропущенных значений.
См. также: skipmissing
, nonmissingtype
, Nothing
.
Base.missing
— Constantmissing
Единственный экземпляр типа Missing
, представляющий отсутствующее значение.
См. также: NaN
, skipmissing
, nonmissingtype
.
Base.coalesce
— Functioncoalesce(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.@coalesce
— Macro@coalesce(x...)
Короткозамыкательная версия coalesce
.
Примеры
julia> f(x) = (println("f($x)"); missing);
julia> a = 1;
julia> a = @coalesce a f(2) f(3) error("`a` все еще отсутствует")
1
julia> b = missing;
julia> b = @coalesce b f(2) f(3) error("`b` все еще отсутствует")
f(2)
f(3)
ERROR: `b` все еще отсутствует
[...]
Этот макрос доступен начиная с Julia 1.7.
Base.ismissing
— FunctionBase.skipmissing
— Functionskipmissing(itr)
Возвращает итератор по элементам в itr
, пропуская значения missing
. Возвращаемый объект может быть индексирован с использованием индексов itr
, если последний индексируемый. Индексы, соответствующие отсутствующим значениям, недействительны: они пропускаются функциями keys
и eachindex
, и возникает MissingException
, когда вы пытаетесь их использовать.
Используйте collect
, чтобы получить Array
, содержащий ненулевые значения в 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.nonmissingtype
— Functionnonmissingtype(T::Type)
Если T
является объединением типов, содержащих Missing
, верните новый тип с удаленным Missing
.
Примеры
julia> nonmissingtype(Union{Int64,Missing})
Int64
julia> nonmissingtype(Any)
Any
Эта функция экспортируется начиная с Julia 1.3.
System
Base.run
— Functionrun(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.devnull
— Constantdevnull
Используется в перенаправлении потока для отбрасывания всех данных, записанных в него. По сути, эквивалентно /dev/null
в Unix или NUL
в Windows. Использование:
run(pipeline(`cat test.txt`, devnull))
Base.success
— Functionsuccess(command)
Запустите объект команды, созданный с помощью обратных кавычек (см. раздел Запуск внешних программ в руководстве), и сообщите, был ли он успешным (завершился с кодом 0). Исключение возникает, если процесс не может быть запущен.
Base.process_running
— Functionprocess_running(p::Process)
Определите, выполняется ли процесс в данный момент.
Base.process_exited
— Functionprocess_exited(p::Process)
Определите, завершился ли процесс.
Base.kill
— Methodkill(p::Process, signum=Base.SIGTERM)
Отправляет сигнал процессу. По умолчанию процесс завершается. Возвращает успешно, если процесс уже завершился, но вызывает ошибку, если завершение процесса не удалось по другим причинам (например, недостаточные права доступа).
Base.Sys.set_process_title
— FunctionSys.set_process_title(title::AbstractString)
Установите заголовок процесса. Не выполняет никаких действий в некоторых операционных системах.
Base.Sys.get_process_title
— FunctionSys.get_process_title()
Получить заголовок процесса. На некоторых системах всегда будет возвращать пустую строку.
Base.ignorestatus
— Functionignorestatus(command)
Отметьте объект команды так, чтобы его выполнение не выдавало ошибку, если код результата не равен нулю.
Base.detach
— Functiondetach(command)
Отметьте объект команды, чтобы он выполнялся в новой группе процессов, позволяя ему пережить процесс julia и не получать прерывания Ctrl-C.
Base.Cmd
— TypeCmd(cmd::Cmd; ignorestatus, detach, windows_verbatim, windows_hide, env, dir)
Cmd(exec::Vector{String})
Создайте новый объект Cmd
, представляющий внешнюю программу и аргументы, из cmd
, изменяя настройки необязательных аргументов:
ignorestatus::Bool
: Еслиtrue
(по умолчаниюfalse
), тоCmd
не вызовет ошибку, если код возврата не равен нулю.detach::Bool
: Еслиtrue
(по умолчаниюfalse
), тоCmd
будет запущен в новой группе процессов, что позволит ему пережить процессjulia
и не получать сигнал Ctrl-C.windows_verbatim::Bool
: Еслиtrue
(по умолчаниюfalse
), то в WindowsCmd
отправит строку командной строки в процесс без кавычек или экранирования аргументов, даже если аргументы содержат пробелы. (В 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(exec)
не создает копию exec
. Любые последующие изменения в exec
будут отражены в объекте Cmd
.
Наиболее распространенный способ создания объекта Cmd
— с помощью литералов команд (обратные кавычки), например:
`ls -l`
Это затем можно передать конструктору Cmd
, чтобы изменить его настройки, например:
Cmd(`echo "Hello world"`, ignorestatus=true, detach=false)
Base.setenv
— Functionsetenv(command::Cmd, env; dir)
Установите переменные окружения для использования при выполнении данной команды
. env
может быть либо словарем, сопоставляющим строки со строками, массивом строк формата "var=val"
, либо ноль или более пар аргументов "var"=>val
. Чтобы изменить (а не заменить) существующее окружение, создайте env
с помощью copy(ENV)
и затем установите env["var"]=val
по мере необходимости, или используйте addenv
.
Аргумент ключевого слова dir
может быть использован для указания рабочей директории для команды. dir
по умолчанию устанавливается в текущую установленную dir
для команды
(которая является текущей рабочей директорией, если не указана ранее).
Base.addenv
— Functionaddenv(command::Cmd, env...; inherit::Bool = true)
Объединяет новые сопоставления окружения в данный Cmd
объект, возвращая новый объект Cmd
. Дубликаты ключей заменяются. Если command
не содержит никаких значений окружения, он наследует текущее окружение на момент вызова addenv()
, если inherit
равно true
. Ключи со значением nothing
удаляются из окружения.
Эта функция требует Julia 1.6 или более поздней версии.
Base.withenv
— Functionwithenv(f, kv::Pair...)
Выполните f
в среде, которая временно изменена (а не заменена, как в setenv
) с помощью нуля или более аргументов "var"=>val
kv
. withenv
обычно используется через синтаксис withenv(kv...) do ... end
. Значение nothing
может быть использовано для временного сброса переменной окружения (если она установлена). Когда withenv
возвращает, оригинальная среда восстанавливается.
Изменение окружения не является потокобезопасным. Для выполнения внешних команд с другой средой, отличной от родительского процесса, предпочтительнее использовать addenv
вместо withenv
.
Base.setcpuaffinity
— Functionsetcpuaffinity(original_command::Cmd, cpus) -> command::Cmd
Установите привязку процессора для command
с помощью списка идентификаторов процессоров (начиная с 1) cpus
. Передача cpus = nothing
означает сброс привязки процессора, если у original_command
есть таковая.
Эта функция поддерживается только в Linux и Windows. Она не поддерживается в macOS, потому что libuv не поддерживает установку привязки.
Эта функция требует как минимум 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.pipeline
— Methodpipeline(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.pipeline
— Methodpipeline(command; stdin, stdout, stderr, append=false)
Перенаправляет ввод/вывод к или от данного command
. Ключевые аргументы указывают, какие из потоков команды должны быть перенаправлены. append
управляет тем, добавляется ли вывод в файл. Это более общая версия функции pipeline
с 2 аргументами. 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.gethostname
— Functiongethostname() -> String
Получите имя хоста локальной машины.
Base.Libc.getpid
— Functiongetpid() -> Int32
Получить идентификатор процесса Julia.
getpid(process) -> Int32
Получите идентификатор дочернего процесса, если он все еще существует.
Эта функция требует как минимум Julia 1.1.
Base.Libc.time
— Methodtime() -> Float64
Получите системное время в секундах с начала эпохи с довольно высокой (обычно микросекундной) разрешающей способностью.
Base.time_ns
— Functiontime_ns() -> UInt64
Получите время в наносекундах. Время, соответствующее 0, не определено и обнуляется каждые 5,8 лет.
Base.@time
— Macro@time expr
@time "описание" expr
Макрос для выполнения выражения, печатающий время, затраченное на выполнение, количество аллокаций и общее количество байт, которые были выделены в процессе выполнения, перед возвратом значения выражения. Время, затраченное на сборку мусора (gc), компиляцию нового кода или перекомпиляцию недействительного кода, отображается в процентах. Любые конфликты блокировок, когда ReentrantLock
должен был ждать, отображаются в виде количества.
Опционально предоставьте строку описания для печати перед отчетом о времени.
В некоторых случаях система будет заглядывать внутрь выражения @time
и компилировать некоторый вызываемый код перед началом выполнения верхнего уровня выражения. Когда это происходит, часть времени компиляции не будет учтена. Чтобы включить это время, вы можете запустить @time @eval ...
.
См. также @showtime
, @timev
, @timed
, @elapsed
, @allocated
и @allocations
.
Для более серьезного бенчмаркинга рассмотрите макрос @btime
из пакета BenchmarkTools.jl, который, среди прочего, оценивает функцию несколько раз, чтобы уменьшить шум.
Опция добавления описания была введена в Julia 1.8.
Время перекомпиляции, отображаемое отдельно от времени компиляции, было введено в Julia 1.8
Отчет о любых конфликтах блокировок был добавлен в Julia 1.11.
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 "Один секундный сон" sleep(1)
Один секундный сон: 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.@showtime
— Macro@showtime expr
Как @time
, но также выводит выражение, которое оценивается для справки.
Этот макрос был добавлен в Julia 1.8.
См. также @time
.
julia> @showtime sleep(1)
sleep(1): 1.002164 секунды (4 аллокации: 128 байт)
Base.@timev
— Macro@timev expr
@timev "описание" expr
Это подробная версия макроса @time
. Сначала он выводит ту же информацию, что и @time
, затем любые счетчики выделения памяти, отличные от нуля, и затем возвращает значение выражения.
При желании можно предоставить строку описания, чтобы вывести ее перед отчетом о времени.
Возможность добавить описание была введена в 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.@timed
— Macro@timed
Макрос для выполнения выражения и возврата значения выражения, времени выполнения в секундах, общего объема выделенной памяти, времени сборки мусора, объекта с различными счетчиками выделения памяти, времени компиляции в секундах и времени повторной компиляции в секундах. Любые конфликты блокировок, когда ReentrantLock
должен был ждать, отображаются в виде счетчика.
В некоторых случаях система будет заглядывать внутрь выражения @timed
и компилировать часть вызываемого кода до начала выполнения верхнего уровня выражения. Когда это происходит, часть времени компиляции не будет учтена. Чтобы включить это время, вы можете выполнить @timed @eval ...
.
См. также @time
, @timev
, @elapsed
, @allocated
, @allocations
и @lock_conflicts
.
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> stats.compile_time
0.0
julia> stats.recompile_time
0.0
Возвращаемый тип этого макроса был изменен с Tuple
на NamedTuple
в Julia 1.5.
Поля lock_conflicts
, compile_time
и recompile_time
были добавлены в Julia 1.11.
Base.@elapsed
— Macro@elapsed
Макрос для оценки выражения, игнорируя полученное значение, вместо этого возвращая количество секунд, которое потребовалось для выполнения, в виде числа с плавающей запятой.
В некоторых случаях система будет заглядывать внутрь выражения @elapsed
и компилировать часть вызываемого кода до начала выполнения верхнего уровня выражения. Когда это происходит, часть времени компиляции не будет учтена. Чтобы включить это время, вы можете выполнить @elapsed @eval ...
.
См. также @time
, @timev
, @timed
, @allocated
и @allocations
.
julia> @elapsed sleep(0.3)
0.301391426
Base.@allocated
— Macro@allocated
Макрос для оценки выражения, игнорируя полученное значение, вместо этого возвращая общее количество байт, выделенных во время оценки выражения.
См. также @allocations
, @time
, @timev
, @timed
и @elapsed
.
julia> @allocated rand(10^6)
8000080
Base.@allocations
— Macro@allocations
Макрос для оценки выражения, отбрасывания полученного значения и вместо этого возвращения общего числа аллокаций во время оценки выражения.
См. также @allocated
, @time
, @timev
, @timed
и @elapsed
.
julia> @allocations rand(10^6)
2
Этот макрос был добавлен в Julia 1.9.
Base.@lock_conflicts
— Macro@lock_conflicts
Макрос для оценки выражения, отбрасывающий полученное значение и вместо этого возвращающий общее количество конфликтов блокировки во время оценки, когда попытка блокировки на ReentrantLock
привела к ожиданию, потому что блокировка уже была удерживаемой.
См. также @time
, @timev
и @timed
.
julia> @lock_conflicts begin
l = ReentrantLock()
Threads.@threads for i in 1:Threads.nthreads()
lock(l) do
sleep(1)
end
end
end
5
Этот макрос был добавлен в Julia 1.11.
Base.EnvDict
— TypeEnvDict() -> EnvDict
Одиночный экземпляр этого типа предоставляет интерфейс хеш-таблицы для переменных окружения.
Base.ENV
— ConstantENV
Ссылка на одиночный 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"
Base.Sys.STDLIB
— ConstantSys.STDLIB::String
Строка, содержащая полный путь к директории, содержащей пакеты stdlib
.
Base.Sys.isunix
— FunctionSys.isunix([os])
Предикат для проверки, предоставляет ли ОС интерфейс, подобный Unix. См. документацию в Handling Operating System Variation.
Base.Sys.isapple
— FunctionSys.isapple([os])
Предикат для проверки, является ли ОС производной от Apple Macintosh OS X или Darwin. См. документацию в Handling Operating System Variation.
Base.Sys.islinux
— FunctionSys.islinux([os])
Предикат для проверки, является ли ОС производной от Linux. См. документацию в Handling Operating System Variation.
Base.Sys.isbsd
— FunctionSys.isbsd([os])
Предикат для проверки, является ли ОС производной от BSD. См. документацию в Handling Operating System Variation.
Ядро Darwin происходит от BSD, что означает, что Sys.isbsd()
возвращает true
на системах macOS. Чтобы исключить macOS из предиката, используйте Sys.isbsd() && !Sys.isapple()
.
Base.Sys.isfreebsd
— FunctionSys.isfreebsd([os])
Предикат для проверки, является ли ОС производной FreeBSD. См. документацию в Handling Operating System Variation.
Не путать с Sys.isbsd()
, который возвращает true
на FreeBSD, но также и на других системах на базе BSD. Sys.isfreebsd()
относится только к FreeBSD.
Эта функция требует как минимум Julia 1.1.
Base.Sys.isopenbsd
— FunctionSys.isopenbsd([os])
Предикат для проверки, является ли ОС производной от OpenBSD. См. документацию в Handling Operating System Variation.
Не путать с Sys.isbsd()
, который возвращает true
на OpenBSD, но также и на других системах на базе BSD. Sys.isopenbsd()
относится только к OpenBSD.
Эта функция требует как минимум Julia 1.1.
Base.Sys.isnetbsd
— FunctionSys.isnetbsd([os])
Предикат для проверки, является ли ОС производной от NetBSD. См. документацию в Handling Operating System Variation.
Не путать с Sys.isbsd()
, который возвращает true
на NetBSD, но также и на других системах на базе BSD. Sys.isnetbsd()
относится только к NetBSD.
Эта функция требует как минимум Julia 1.1.
Base.Sys.isdragonfly
— FunctionSys.isdragonfly([os])
Предикат для проверки, является ли ОС производной DragonFly BSD. См. документацию в Handling Operating System Variation.
Не путать с Sys.isbsd()
, который возвращает true
на DragonFly, но также и на других системах на базе BSD. Sys.isdragonfly()
относится только к DragonFly.
Эта функция требует как минимум Julia 1.1.
Base.Sys.iswindows
— FunctionSys.iswindows([os])
Предикат для проверки, является ли ОС производной от Microsoft Windows NT. См. документацию в Handling Operating System Variation.
Base.Sys.windows_version
— FunctionSys.windows_version()
Возвращает номер версии для ядра Windows NT в виде VersionNumber
, т.е. v"major.minor.build"
, или v"0.0.0"
, если это не работает на Windows.
Base.Sys.free_memory
— FunctionSys.free_memory()
Получите общий объем свободной памяти в ОЗУ в байтах.
Base.Sys.total_memory
— FunctionSys.total_memory()
Получите общий объем памяти в ОЗУ (включая ту, которая в настоящее время используется) в байтах. Эта сумма может быть ограничена, например, группами управления Linux. Для неограниченного объема см. Sys.total_physical_memory()
.
Base.Sys.free_physical_memory
— FunctionSys.free_physical_memory()
Получите свободную память системы в байтах. Вся сумма может быть недоступна для текущего процесса; используйте Sys.free_memory()
, чтобы получить фактически доступное количество.
Base.Sys.total_physical_memory
— FunctionSys.total_physical_memory()
Получите общий объем памяти в ОЗУ (включая ту, которая в настоящее время используется) в байтах. Весь объем может быть недоступен для текущего процесса; см. Sys.total_memory()
.
Base.Sys.uptime
— FunctionSys.uptime()
Получает текущее время работы системы в секундах.
Base.Sys.isjsvm
— FunctionSys.isjsvm([os])
Предикат для проверки, работает ли Julia в виртуальной машине JavaScript (JSVM), включая, например, встраивание JavaScript WebAssembly в веб-браузере.
Эта функция требует как минимум Julia 1.2.
Base.Sys.loadavg
— FunctionSys.loadavg()
Получить среднюю нагрузку. См.: https://en.wikipedia.org/wiki/Load_(computing).
Base.Sys.isexecutable
— Functionisexecutable(path::String)
Возвращает true
, если указанный path
имеет разрешения на выполнение.
Это разрешение может измениться до того, как пользователь выполнит path
, поэтому рекомендуется выполнить файл и обработать ошибку, если это не удастся, вместо того чтобы сначала вызывать isexecutable
.
До Julia 1.6 это не корректно проверяло ACL файловой системы в Windows, поэтому оно возвращало true
для любого файла. Начиная с Julia 1.6, оно правильно определяет, помечен ли файл как исполняемый или нет.
См. также ispath
, isreadable
, iswritable
.
Base.Sys.isreadable
— Functionisreadable(path::String)
Возвращает true
, если права доступа для данного path
разрешают чтение текущим пользователем.
Эти права могут измениться до того, как пользователь вызовет open
, поэтому рекомендуется просто вызывать open
и обрабатывать ошибку, если это не удастся, вместо того чтобы сначала вызывать isreadable
.
В настоящее время эта функция не корректно проверяет ACL файловой системы в Windows, поэтому она может возвращать неправильные результаты.
Эта функция требует как минимум Julia 1.11.
См. также ispath
, isexecutable
, iswritable
.
isreadable(io) -> Bool
Возвращает false
, если указанный объект IO не доступен для чтения.
Примеры
julia> open("myfile.txt", "w") do io
print(io, "Hello world!");
isreadable(io)
end
false
julia> open("myfile.txt", "r") do io
isreadable(io)
end
true
julia> rm("myfile.txt")
Base.Sys.iswritable
— Functioniswritable(path::String)
Возвращает true
, если права доступа для данного path
разрешают запись текущему пользователю.
Эти права могут измениться до того, как пользователь вызовет open
, поэтому рекомендуется просто вызывать open
и обрабатывать ошибку, если она возникнет, вместо того чтобы сначала вызывать iswritable
.
В настоящее время эта функция не корректно проверяет ACL файловой системы в Windows, поэтому она может возвращать неверные результаты.
Эта функция требует как минимум Julia 1.11.
См. также ispath
, isexecutable
, isreadable
.
iswritable(io) -> Bool
Возвращает false
, если указанный объект IO не доступен для записи.
Примеры
julia> open("myfile.txt", "w") do io
print(io, "Hello world!");
iswritable(io)
end
true
julia> open("myfile.txt", "r") do io
iswritable(io)
end
false
julia> rm("myfile.txt")
Base.Sys.username
— FunctionSys.username() -> String
Возвращает имя пользователя для текущего пользователя. Если имя пользователя не может быть определено или пусто, эта функция вызывает ошибку.
Чтобы получить имя пользователя, которое можно переопределить с помощью переменной окружения, например, USER
, рассмотрите возможность использования
user = get(Sys.username, ENV, "USER")
Эта функция требует как минимум Julia 1.11.
См. также homedir
.
Base.@static
— Macro@static
Частично оценить выражение во время разбора.
Например, @static Sys.iswindows() ? foo : bar
оценит Sys.iswindows()
и вставит либо foo
, либо bar
в выражение. Это полезно в случаях, когда конструкция была бы недопустима на других платформах, таких как ccall
к несуществующей функции. @static if Sys.isapple() foo end
и @static foo <&&,||> bar
также являются допустимым синтаксисом.
Versioning
Base.VersionNumber
— TypeVersionNumber
Тип номера версии, который соответствует спецификациям семантического версионирования (semver), состоит из основных, второстепенных и патч-числовых значений, за которыми следуют аннотации предварительного выпуска и сборки в алфавитно-цифровом формате.
Объекты VersionNumber
могут быть сравнены со всеми стандартными операторами сравнения (==
, <
, <=
и т.д.), при этом результат будет следовать правилам semver.
VersionNumber
имеет следующие публичные поля:
v.major::Integer
v.minor::Integer
v.patch::Integer
v.prerelease::Tuple{Vararg{Union{Integer, AbstractString}}}
v.build::Tuple{Vararg{Union{Integer, AbstractString}}}
Смотрите также @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_str
— Macro@v_str
Строковый макрос, используемый для разбора строки в VersionNumber
.
Примеры
julia> v"1.2.3"
v"1.2.3"
julia> v"2.0.1-rc1"
v"2.0.1-rc1"
Errors
Base.error
— Functionerror(message::AbstractString)
Вызывает ErrorException
с заданным сообщением.
error(msg...)
Вызывает ErrorException
с сообщением, сконструированным с помощью string(msg...)
.
Core.throw
— FunctionBase.rethrow
— Functionrethrow()
Повторно выбросьте текущее исключение из блока catch
. Повторно выброшенное исключение будет продолжать распространяться так, как будто оно не было перехвачено.
Альтернативная форма rethrow(e)
позволяет вам ассоциировать альтернативный объект исключения e
с текущим трассировкой стека. Однако это искажает состояние программы в момент ошибки, поэтому рекомендуется вместо этого выбросить новое исключение, используя throw(e)
. В Julia 1.1 и выше использование throw(e)
сохранит исключение коренной причины в стеке, как описано в current_exceptions
.
Base.backtrace
— Functionbacktrace()
Получите объект обратного вызова для текущей точки программы.
Base.catch_backtrace
— Functioncatch_backtrace()
Получите трассировку стека текущего исключения для использования в блоках catch
.
Base.current_exceptions
— Functioncurrent_exceptions(task::Task=current_task(); [backtrace::Bool=true])
Получите стек исключений, которые в настоящее время обрабатываются. Для вложенных блоков catch может быть более одного текущего исключения, в этом случае последнее выброшенное исключение будет последним в стеке. Стек возвращается как ExceptionStack
, который является AbstractVector именованных кортежей (exception,backtrace)
. Если backtrace
ложный, то трассировка в каждой паре будет установлена в nothing
.
Явная передача task
вернет текущий стек исключений для произвольной задачи. Это полезно для проверки задач, которые завершились с ошибкой из-за необработанных исключений.
Эта функция носила экспериментальное название catch_stack()
в Julia 1.1–1.6 и имела простой Vector-of-tuples в качестве типа возвращаемого значения.
Base.@assert
— Macro@assert cond [text]
Вызывает AssertionError
, если cond
равно false
. Это предпочтительный синтаксис для написания утверждений, которые являются условиями, предполагаемыми как истинные, но которые пользователь может решить проверить, как помощь в отладке, если они не выполняются. Необязательное сообщение text
отображается при сбое утверждения.
Утверждение может быть отключено на некоторых уровнях оптимизации. Поэтому утверждения следует использовать только как инструмент отладки и не использовать для проверки аутентификации (например, для проверки паролей или проверки границ массива). Код не должен полагаться на побочные эффекты выполнения cond
для правильного поведения функции.
Примеры
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_hint
— FunctionExperimental.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, "\nВы имели в виду вызвать ")
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)
Функция `only_int` существует, но ни один метод не определен для этой комбинации типов аргументов.
Вы имели в виду вызвать `any_number`?
Ближайшие кандидаты:
...
Пользовательские подсказки ошибок доступны начиная с Julia 1.5.
Этот интерфейс является экспериментальным и может быть изменен или удален без предварительного уведомления. Чтобы защитить себя от изменений, рассмотрите возможность размещения любых регистраций внутри блока if isdefined(Base.Experimental, :register_error_hint) ... end
.
Base.Experimental.show_error_hints
— FunctionExperimental.show_error_hints(io, ex, args...)
Вызовите все обработчики из Experimental.register_error_hint
для данного типа исключения typeof(ex)
. args
должны содержать любые другие аргументы, ожидаемые обработчиком для этого типа.
Пользовательские подсказки об ошибках доступны начиная с Julia 1.5.
Этот интерфейс является экспериментальным и может быть изменен или удален без предварительного уведомления.
Core.ArgumentError
— TypeArgumentError(msg)
Аргументы, переданные функции, недействительны. msg
— это описательное сообщение об ошибке.
Core.AssertionError
— TypeAssertionError([msg])
Утвержденное условие не оценивалось как true
. Необязательный аргумент msg
— это описательная строка ошибки.
Примеры
julia> @assert false "this is not true"
ERROR: AssertionError: this is not true
AssertionError
обычно выбрасывается из @assert
.
Core.BoundsError
— TypeBoundsError([a],[i])
Операция индексирования в массиве a
попыталась получить доступ к элементу вне границ по индексу i
.
Примеры
julia> A = fill(1.0, 7);
julia> A[8]
ERROR: BoundsError: попытка доступа к 7-элементному вектору {Float64} по индексу [8]
julia> B = fill(1.0, (2,3));
julia> B[2, 4]
ERROR: BoundsError: попытка доступа к 2×3 матрице {Float64} по индексу [2, 4]
julia> B[9]
ERROR: BoundsError: попытка доступа к 2×3 матрице {Float64} по индексу [9]
Base.CompositeException
— TypeCompositeException
Оборачивает Vector
исключений, выброшенных Task
(например, сгенерированных удаленным работником через канал или асинхронно выполняющейся локальной записью ввода-вывода или удаленным работником под pmap
), с информацией о серии исключений. Например, если группа работников выполняет несколько задач, и несколько работников терпят неудачу, результирующий CompositeException
будет содержать "пакет" информации от каждого работника, указывающий, где и почему произошли исключения.
Base.DimensionMismatch
— TypeDimensionMismatch([msg])
Объекты, которые были вызваны, не имеют совпадающей размерности. Необязательный аргумент msg
— это описательная строка ошибки.
Core.DivideError
— TypeDivideError()
Попытка целочисленного деления с делителем, равным 0.
Примеры
julia> 2/0
Inf
julia> div(2, 0)
ERROR: DivideError: ошибка целочисленного деления
Stacktrace:
[...]
Core.DomainError
— TypeDomainError(val)
DomainError(val, msg)
Аргумент val
для функции или конструктора находится вне допустимой области.
Примеры
julia> sqrt(-1)
ERROR: DomainError with -1.0:
sqrt был вызван с отрицательным действительным аргументом, но вернет комплексный результат только при вызове с комплексным аргументом. Попробуйте sqrt(Complex(x)).
Stacktrace:
[...]
Base.EOFError
— TypeEOFError()
Больше не было доступных данных для чтения из файла или потока.
Core.ErrorException
— TypeErrorException(msg)
Общий тип ошибки. Сообщение об ошибке в поле .msg
может содержать более конкретные детали.
Примеры
julia> ex = ErrorException("Я сделал плохую вещь");
julia> ex.msg
"Я сделал плохую вещь"
Core.InexactError
— TypeInexactError(name::Symbol, T, val)
Не удается точно преобразовать val
в тип T
в методе функции name
.
Примеры
julia> convert(Float64, 1+2im)
ERROR: InexactError: Float64(1 + 2im)
Stacktrace:
[...]
Core.InterruptException
— TypeInterruptException()
Процесс был остановлен терминальным прерыванием (CTRL+C).
Обратите внимание, что в скрипте Julia, запущенном без опции -i
(интерактивный), InterruptException
по умолчанию не выбрасывается. Вызов Base.exit_on_sigint(false)
в скрипте может восстановить поведение REPL. В качестве альтернативы, скрипт Julia можно запустить с
julia -e "include(popfirst!(ARGS))" script.jl
чтобы позволить InterruptException
быть выброшенным при нажатии CTRL+C во время выполнения.
Base.KeyError
— TypeKeyError(key)
Операция индексирования в AbstractDict
(Dict
) или объекте, подобном Set
, попыталась получить доступ к несуществующему элементу или удалить его.
Core.LoadError
— TypeLoadError(file::AbstractString, line::Int, error)
Произошла ошибка при include
, require
или using
файла. Подробности об ошибке должны быть доступны в поле .error
.
LoadErrors больше не генерируются @macroexpand
, @macroexpand1
и macroexpand
начиная с Julia 1.7.
Core.MethodError
— TypeMethodError(f, args)
Метод с требуемой сигнатурой типа не существует в данной обобщенной функции. В качестве альтернативы, нет уникального наиболее специфичного метода.
Base.MissingException
— TypeMissingException(msg)
Исключение, выбрасываемое, когда встречается missing
значение в ситуации, где оно не поддерживается. Сообщение об ошибке в поле msg
может предоставить более конкретные детали.
Core.OutOfMemoryError
— TypeOutOfMemoryError()
Операция выделила слишком много памяти, чтобы система или сборщик мусора могли правильно с этим справиться.
Core.ReadOnlyMemoryError
— TypeReadOnlyMemoryError()
Операция попыталась записать в память, которая является только для чтения.
Core.OverflowError
— TypeOverflowError(msg)
Результат выражения слишком велик для указанного типа и приведет к переполнению.
Base.ProcessFailedException
— TypeProcessFailedException
Указывает на проблемный код завершения процесса. При выполнении команд или конвейеров это исключение выбрасывается, чтобы указать, что был возвращен ненулевой код завершения (т.е. что вызванный процесс завершился с ошибкой).
Base.TaskFailedException
— TypeTaskFailedException
Это исключение выбрасывается вызовом wait(t)
, когда задача t
завершается с ошибкой. TaskFailedException
оборачивает неудавшуюся задачу t
.
Core.StackOverflowError
— TypeStackOverflowError()
Вызов функции превысил размер стека вызовов. Это обычно происходит, когда вызов рекурсивен бесконечно.
Base.SystemError
— TypeSystemError(prefix::AbstractString, [errno::Int32])
Системный вызов завершился неудачей с кодом ошибки (в глобальной переменной errno
).
Core.TypeError
— TypeTypeError(func::Symbol, context::AbstractString, expected::Type, got)
Ошибка утверждения типа или вызов встроенной функции с неправильным типом аргумента.
Core.UndefKeywordError
— TypeUndefKeywordError(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.UndefRefError
— TypeUndefRefError()
Элемент или поле не определены для данного объекта.
Примеры
julia> struct MyType
a::Vector{Int}
MyType() = new()
end
julia> A = MyType()
MyType(#undef)
julia> A.a
ERROR: UndefRefError: доступ к неопределенной ссылке
Stacktrace:
[...]
Core.UndefVarError
— TypeUndefVarError(var::Symbol, [scope])
Символ в текущей области видимости не определен.
Примеры
julia> a
ERROR: UndefVarError: `a` not defined in `Main`
julia> a = 1;
julia> a
1
Base.StringIndexError
— TypeStringIndexError(str, i)
Произошла ошибка при попытке получить доступ к str
по индексу i
, который недействителен.
Core.InitError
— TypeInitError(mod::Symbol, error)
Произошла ошибка при выполнении функции __init__
модуля. Фактическая ошибка, вызванная исключением, доступна в поле .error
.
Base.retry
— Functionretry(f; delays=ExponentialBackOff(), check=nothing) -> Function
Возвращает анонимную функцию, которая вызывает функцию f
. Если возникает исключение, f
повторно вызывается, каждый раз, когда check
возвращает true
, после ожидания количества секунд, указанного в delays
. check
должен принимать текущее состояние delays
и Exception
.
До 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.ExponentialBackOff
— TypeExponentialBackOff(; 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
.
Events
Base.Timer
— MethodTimer(callback::Function, delay; interval = 0)
Создайте таймер, который запускает функцию callback
при каждом истечении времени таймера.
Ожидающие задачи пробуждаются, и функция callback
вызывается после начальной задержки в delay
секунд, а затем повторяется с заданным интервалом в секундах. Если interval
равен 0
, обратный вызов выполняется только один раз. Функция callback
вызывается с одним аргументом, самим таймером. Остановите таймер, вызвав close
. Обратный вызов может быть выполнен еще один последний раз, если таймер уже истек.
Примеры
Здесь первое число выводится после задержки в две секунды, затем следующие числа выводятся быстро.
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.Timer
— TypeТаймер(задержка; интервал = 0)
Создайте таймер, который пробуждает задачи, ожидающие его (вызывая wait
на объекте таймера).
Ожидающие задачи пробуждаются после начальной задержки не менее задержка
секунд, а затем повторяются после того, как пройдет не менее интервал
секунд. Если интервал
равен 0
, таймер срабатывает только один раз. Когда таймер закрыт (вызывая close
), ожидающие задачи пробуждаются с ошибкой. Используйте isopen
, чтобы проверить, активен ли таймер.
!!! примечание интервал
подвержен накоплению временного сдвига. Если вам нужны точные события в определенное абсолютное время, создайте новый таймер при каждом истечении времени с учетом разницы до следующего времени.
!!! примечание Таймер
требует точек выхода для обновления своего состояния. Например, isopen(t::Timer)
не может быть использован для тайм-аута в невыходном цикле while.
Base.AsyncCondition
— TypeAsyncCondition()
Создайте асинхронное условие, которое пробуждает задачи, ожидающие его (вызывая wait
на объекте), когда оно уведомляется из C с помощью вызова uv_async_send
. Ожидающие задачи пробуждаются с ошибкой, когда объект закрыт (с помощью close
). Используйте isopen
, чтобы проверить, активно ли оно еще.
Это обеспечивает неявный порядок памяти для захвата и освобождения между отправляющими и ожидающими потоками.
Base.AsyncCondition
— MethodAsyncCondition(callback::Function)
Создайте асинхронное условие, которое вызывает заданную функцию callback
. Функция callback
принимает один аргумент — сам объект асинхронного условия.
Reflection
Base.nameof
— Methodnameof(m::Module) -> Symbol
Получите имя Module
в виде Symbol
.
Примеры
julia> nameof(Base.Broadcast)
:Broadcast
Base.parentmodule
— Functionparentmodule(m::Module) -> Module
Получить родительский Module
модуля. Main
является своим собственным родителем.
Смотрите также: names
, nameof
, fullname
, @__MODULE__
.
Примеры
julia> parentmodule(Main)
Main
julia> parentmodule(Base.Broadcast)
Base
parentmodule(t::DataType) -> Module
Определите модуль, содержащий определение (возможно, обернутого в UnionAll
) DataType
.
Примеры
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
Определите модуль, содержащий первый метод обобщенной функции f
, соответствующий указанным types
.
parentmodule(m::Method) -> Module
Возвращает модуль, в котором определен данный метод m
.
Передача Method
в качестве аргумента требует Julia 1.9 или более поздней версии.
Base.pathof
— Methodpathof(m::Module)
Возвращает путь к файлу m.jl
, который был использован для import
модуля m
, или nothing
, если m
не был импортирован из пакета.
Используйте dirname
, чтобы получить часть каталога, и basename
, чтобы получить часть имени файла пути.
Смотрите также pkgdir
.
Base.pkgdir
— Methodpkgdir(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"
См. также pathof
.
Необязательный аргумент paths
требует как минимум Julia 1.7.
Base.pkgversion
— Methodpkgversion(m::Module)
Возвращает версию пакета, который импортировал модуль m
, или nothing
, если m
не был импортирован из пакета или был импортирован из пакета без установленного поля версии.
Версия считывается из Project.toml пакета во время загрузки пакета.
Чтобы получить версию пакета, который импортировал текущий модуль, можно использовать форму pkgversion(@__MODULE__)
.
Эта функция была введена в Julia 1.9.
Base.moduleroot
— Functionmoduleroot(m::Module) -> Module
Найдите корневой модуль данного модуля. Это первый модуль в цепочке родительских модулей m
, который является либо зарегистрированным корневым модулем, либо является своим собственным родительским модулем.
__module__
— Keyword__module__
Аргумент __module__
виден только внутри макроса и предоставляет информацию (в виде объекта Module
) о контексте расширения вызова макроса. См. раздел справки о Вызове макросов для получения дополнительной информации.
__source__
— Keyword__source__
Аргумент __source__
виден только внутри макроса и предоставляет информацию (в виде объекта LineNumberNode
) о местоположении парсера знака @
из вызова макроса. См. раздел справочного руководства о Вызове макросов для получения дополнительной информации.
Base.@__MODULE__
— Macro@__MODULE__ -> Модуль
Получите Модуль
верхнего уровня eval, который является Модулем
, из которого в настоящее время читается код.
Base.@__FILE__
— Macro@__FILE__ -> String
Расширяет до строки с путем к файлу, содержащему вызов макроса, или пустой строки, если оценено с помощью julia -e <expr>
. Возвращает nothing
, если у макроса отсутствует информация о исходном коде парсера. В качестве альтернативы см. PROGRAM_FILE
.
Base.@__DIR__
— Macro@__DIR__ -> String
Макрос для получения абсолютного пути текущего каталога в виде строки.
Если используется в скрипте, возвращает каталог скрипта, содержащего вызов макроса @__DIR__
. Если запущен из REPL или если оценен с помощью julia -e <expr>
, возвращает текущий рабочий каталог.
Примеры
Пример иллюстрирует разницу в поведении @__DIR__
и pwd()
, создавая простой скрипт в другом каталоге, чем текущий рабочий, и выполняя обе команды:
julia> cd("/home/JuliaUser") # рабочий каталог
julia> # создаем скрипт в /home/JuliaUser/Projects
open("/home/JuliaUser/Projects/test.jl","w") do io
print(io, """
println("@__DIR__ = ", @__DIR__)
println("pwd() = ", pwd())
""")
end
julia> # выводит каталог скрипта и текущий рабочий каталог
include("/home/JuliaUser/Projects/test.jl")
@__DIR__ = /home/JuliaUser/Projects
pwd() = /home/JuliaUser
Base.@__LINE__
— Macro@__LINE__ -> Int
Расширяется до номера строки, где находится вызов макроса. Возвращает 0
, если номер строки не может быть определен.
Base.fullname
— Functionfullname(m::Module)
Получите полное имя модуля в виде кортежа символов. Например,
Примеры
julia> fullname(Base.Iterators)
(:Base, :Iterators)
julia> fullname(Main)
(:Main,)
Base.names
— Functionnames(x::Module; all::Bool = false, imported::Bool = false)
Получите вектор публичных имен модуля Module
, исключая устаревшие имена. Если all
равно true, то список также включает непубличные имена, определенные в модуле, устаревшие имена и имена, сгенерированные компилятором. Если imported
равно true, то также включаются имена, явно импортированные из других модулей. Имена возвращаются в отсортированном порядке.
В качестве особого случая все имена, определенные в Main
, считаются "публичными", так как не является идиоматичным явно помечать имена из Main
как публичные.
sym ∈ names(SomeModule)
не подразумевает isdefined(SomeModule, sym)
. names
вернет символы, помеченные как public
или export
, даже если они не определены в модуле.
См. также: Base.isexported
, Base.ispublic
, Base.@locals
, @__MODULE__
.
Base.isexported
— Functionisexported(m::Module, s::Symbol) -> Bool
Возвращает, экспортирован ли символ из модуля.
julia> module Mod
export foo
public bar
end
Mod
julia> Base.isexported(Mod, :foo)
true
julia> Base.isexported(Mod, :bar)
false
julia> Base.isexported(Mod, :baz)
false
Base.ispublic
— Functionispublic(m::Module, s::Symbol) -> Bool
Возвращает, помечен ли символ как публичный в модуле.
Экспортированные символы считаются публичными.
Эта функция и понятие публичности были добавлены в Julia 1.11.
См. также: isexported
, names
julia> module Mod
export foo
public bar
end
Mod
julia> Base.ispublic(Mod, :foo)
true
julia> Base.ispublic(Mod, :bar)
true
julia> Base.ispublic(Mod, :baz)
false
Base.nameof
— Methodnameof(f::Function) -> Symbol
Получите имя обобщенной Function
в виде символа. Для анонимных функций это имя, сгенерированное компилятором. Для явно объявленных подтипов Function
это имя типа функции.
Base.functionloc
— Methodfunctionloc(f::Function, types)
Возвращает кортеж (имя_файла, строка)
, указывающий местоположение определения обобщенной Function
.
Base.functionloc
— Methodfunctionloc(m::Method)
Возвращает кортеж (имя_файла, строка)
, указывающий местоположение определения Method
.
Base.@locals
— Macro@locals()
Создает словарь имен (в виде символов) и значений всех локальных переменных, определенных на момент вызова.
Этот макрос требует как минимум Julia 1.1.
Примеры
julia> let x = 1, y = 2
Base.@locals
end
Dict{Symbol, Any} с 2 записями:
: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)
Core.getglobal
— Functiongetglobal(module::Module, name::Symbol, [order::Symbol=:monotonic])
Получите значение связывания name
из модуля module
. При желании можно определить атомарный порядок для операции, в противном случае по умолчанию используется монотонный.
Хотя доступ к связываниям модуля с помощью getfield
по-прежнему поддерживается для сохранения совместимости, всегда следует предпочитать использование getglobal
, так как getglobal
позволяет контролировать атомарный порядок (getfield
всегда монотонный) и лучше обозначает намерения кода как для пользователя, так и для компилятора.
Большинство пользователей не должны вызывать эту функцию напрямую – следует предпочитать функцию getproperty
или соответствующий синтаксис (т.е. module.name
) в большинстве случаев, кроме очень специфических.
Эта функция требует 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!
— Functionsetglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])
Установите или измените значение связывания name
в модуле module
на x
. Преобразование типов не выполняется, поэтому, если для связывания уже было объявлено тип, x
должен быть соответствующего типа, иначе будет выброшена ошибка.
Кроме того, для этой операции можно указать атомарный порядок, в противном случае по умолчанию используется монотонный.
Пользователи обычно получают доступ к этой функциональности через функцию setproperty!
или соответствующий синтаксис (т.е. module.name = x
), поэтому это предназначено только для очень специфических случаев использования.
Эта функция требует Julia 1.9 или более поздней версии.
Смотрите также setproperty!
и getglobal
Примеры
julia> module M; global a; end;
julia> M.a # то же самое, что и `getglobal(M, :a)`
ERROR: UndefVarError: `a` не определен в `M`
Предложение: добавьте соответствующий импорт или присвоение. Этот глобальный объект был объявлен, но не присвоен.
Stacktrace:
[1] getproperty(x::Module, f::Symbol)
@ Base ./Base.jl:42
[2] верхний уровень
@ none:1
julia> setglobal!(M, :a, 1)
1
julia> M.a
1
Core.modifyglobal!
— Functionmodifyglobal!(module::Module, name::Symbol, op, x, [order::Symbol=:monotonic]) -> Pair
Атомарно выполнить операции получения и установки глобальной переменной после применения функции op
.
Эта функция требует Julia 1.11 или более поздней версии.
См. также modifyproperty!
и setglobal!
.
Core.swapglobal!
— Functionswapglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])
Атомарно выполнить операции для одновременного получения и установки глобальной переменной.
Эта функция требует Julia 1.11 или более поздней версии.
См. также swapproperty!
и setglobal!
.
Core.setglobalonce!
— Functionsetglobalonce!(module::Module, name::Symbol, value,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool
Атомарно выполнить операции по установке глобальной переменной в заданное значение, только если она ранее не была установлена.
Эта функция требует Julia 1.11 или более поздней версии.
См. также setpropertyonce!
и setglobal!
.
Core.replaceglobal!
— Functionreplaceglobal!(module::Module, name::Symbol, expected, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)
Атомарно выполнить операции для получения и условной установки глобальной переменной на заданное значение.
Эта функция требует Julia 1.11 или более поздней версии.
См. также replaceproperty!
и setglobal!
.
Documentation
(См. также главу documentation.)
Core.@doc
— MacroДокументация
Функции, методы и типы могут быть задокументированы, если поместить строку перед определением:
"""
# Функция Foo
`foo(x)`: Фу, черт возьми, из `x`.
"""
foo(x) = ...
Макрос @doc
может быть использован напрямую как для установки, так и для получения документации / метаданных. Макрос имеет специальный синтаксис, так что задокументированный объект может находиться на следующей строке:
@doc "blah"
function foo() ...
По умолчанию документация пишется в формате Markdown, но любой объект может быть использован в качестве первого аргумента.
Документирование объектов отдельно от их определений
Вы можете задокументировать объект до или после его определения с помощью
@doc "foo" function_to_doc
@doc "bar" TypeToDoc
Для макросов синтаксис таков: @doc "macro doc" :(Module.@macro)
или @doc "macro doc" :(string_macro"")
для строковых макросов. Без кавычек :()
расширение макроса будет задокументировано.
Получение документации
Вы можете получить документацию для функций, макросов и других объектов следующим образом:
@doc foo
@doc @time
@doc md""
Функции и методы
Помещение документации перед определением метода (например, function foo() ...
или foo() = ...
) приведет к тому, что будет задокументирован именно этот метод, а не вся функция. Документация методов объединяется в порядке их определения, чтобы предоставить документацию для функции.
Base.Docs.HTML
— TypeHTML(s)
: Создайте объект, который отображает s
как html.
HTML("<div>foo</div>")
Вы также можете использовать поток для больших объемов данных:
HTML() do io
println(io, "<div>foo</div>")
end
!!! предупреждение HTML
в настоящее время экспортируется для поддержания обратной совместимости, но этот экспорт устарел. Рекомендуется использовать этот тип как Docs.HTML
или явно импортировать его из Docs
.
Base.Docs.Text
— TypeText(s)
: Создайте объект, который отображает s
как обычный текст.
Text("foo")
Вы также можете использовать поток для больших объемов данных:
Text() do io
println(io, "foo")
end
Text
в настоящее время экспортируется для поддержания обратной совместимости, но этот экспорт устарел. Рекомендуется использовать этот тип как Docs.Text
или явно импортировать его из Docs
.
Base.Docs.hasdoc
— FunctionDocs.hasdoc(mod::Module, sym::Symbol)::Bool
Возвращает true
, если sym
в mod
имеет документационную строку, и false
в противном случае.
Base.Docs.undocumented_names
— Functionundocumented_names(mod::Module; private=false)
Возвращает отсортированный вектор недокументированных символов в module
(то есть, не имеющих строк документации). private=false
(по умолчанию) возвращает только идентификаторы, объявленные с public
и/или export
, в то время как private=true
возвращает все символы в модуле (исключая скрытые символы, сгенерированные компилятором, начинающиеся с #
).
См. также: names
, Docs.hasdoc
, Base.ispublic
.
Code loading
Base.identify_package
— FunctionBase.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 не является зависимостью LinearAlgebra
Base.locate_package
— FunctionBase.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.11/Pkg/src/Pkg.jl"
Base.require
— Functionrequire(into::Module, module::Symbol)
Эта функция является частью реализации using
/ import
, если модуль еще не определен в Main
. Она также может быть вызвана напрямую для принудительной перезагрузки модуля, независимо от того, был ли он загружен ранее (например, при интерактивной разработке библиотек).
Загружает исходный файл в контексте модуля Main
на каждом активном узле, ища стандартные места для файлов. require
считается операцией верхнего уровня, поэтому он устанавливает текущий путь include
, но не использует его для поиска файлов (см. справку по include
). Эта функция обычно используется для загрузки кода библиотек и неявно вызывается using
для загрузки пакетов.
При поиске файлов require
сначала ищет код пакета в глобальном массиве LOAD_PATH
. require
чувствителен к регистру на всех платформах, включая те, которые имеют файловые системы без учета регистра, такие как macOS и Windows.
Для получения дополнительной информации о загрузке кода см. разделы руководства о модулях и параллельных вычислениях.
Base.compilecache
— FunctionBase.compilecache(module::PkgId)
Создает файл предварительной компиляции для модуля и всех его зависимостей. Это можно использовать для сокращения времени загрузки пакетов. Файлы кэша хранятся в DEPOT_PATH[1]/compiled
. См. Инициализация модуля и предварительная компиляция для важных примечаний.
Base.isprecompiled
— FunctionBase.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)
Возвращает, является ли данный PkgId в активном проекте предварительно скомпилированным.
По умолчанию эта проверка использует тот же подход, что и загрузка кода, относительно того, когда разные версии зависимостей в настоящее время загружены, по сравнению с ожидаемым. Чтобы игнорировать загруженные модули и ответить так, как если бы это была новая сессия julia, укажите ignore_loaded=true
.
Эта функция требует как минимум Julia 1.10.
Base.get_extension
— Functionget_extension(parent::Module, extension::Symbol)
Вернуть модуль для extension
родителя или вернуть nothing
, если расширение не загружено.
Internals
Base.GC.gc
— FunctionGC.gc([full=true])
Выполните сборку мусора. Аргумент full
определяет тип сборки: полная сборка (по умолчанию) проходит по всем живым объектам (т.е. полная маркировка) и должна вернуть память от всех недоступных объектов. Инкрементальная сборка возвращает память только от молодых объектов, которые недоступны.
GC может решить выполнить полную сборку, даже если была запрошена инкрементальная сборка.
Чрезмерное использование, вероятно, приведет к плохой производительности.
Base.GC.enable
— FunctionGC.enable(on::Bool)
Управляйте тем, включена ли сборка мусора, с помощью булевого аргумента (true
для включенной, false
для отключенной). Возвращает предыдущее состояние сборки мусора.
Отключение сборки мусора следует использовать только с осторожностью, так как это может привести к неограниченному росту использования памяти.
Base.GC.@preserve
— MacroGC.@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.safepoint
— FunctionGC.safepoint()
Вставляет точку в программе, где может выполняться сборка мусора. Это может быть полезно в редких случаях в многопоточных программах, где некоторые потоки выделяют память (и, следовательно, могут потребовать выполнения сборки мусора), но другие потоки выполняют только простые операции (без выделения, переключения задач или ввода-вывода). Периодический вызов этой функции в невыделяющих потоках позволяет выполнять сборку мусора.
Эта функция доступна начиная с Julia 1.4.
Base.GC.enable_logging
— FunctionGC.enable_logging(on::Bool)
Когда включено, печатает статистику о каждом сборщике мусора в stderr.
Base.GC.logging_enabled
— FunctionGC.logging_enabled()
Возвращает, включено ли ведение журнала сборки мусора через GC.enable_logging
.
Base.Meta.lower
— Functionlower(m, x)
Принимает выражение x
и возвращает эквивалентное выражение в пониженной форме для выполнения в модуле m
. См. также code_lowered
.
Base.Meta.@lower
— Macro@lower [m] x
Возвращает пониженную форму выражения x
в модуле m
. По умолчанию m
— это модуль, в котором вызывается макрос. См. также lower
.
Base.Meta.parse
— Methodparse(str, start; greedy=true, raise=true, depwarn=true, filename="none")
Парсит строку выражения и возвращает выражение (которое позже может быть передано в eval для выполнения). start
— это индекс единицы кода в str
первого символа, с которого нужно начать парсинг (как и при любом индексировании строк, это не индексы символов). Если greedy
равно true
(по умолчанию), parse
попытается потребить как можно больше входных данных; в противном случае он остановится, как только распарсит допустимое выражение. Неполные, но в остальном синтаксически корректные выражения вернут Expr(:incomplete, "(сообщение об ошибке)")
. Если raise
равно true
(по умолчанию), синтаксические ошибки, кроме неполных выражений, вызовут ошибку. Если raise
равно false
, parse
вернет выражение, которое вызовет ошибку при выполнении. Если depwarn
равно false
, предупреждения о депрекации будут подавлены. Аргумент filename
используется для отображения диагностики, когда возникает ошибка.
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.parse
— Methodparse(str; raise=true, depwarn=true, filename="none")
Парсит строку выражения жадно, возвращая одно выражение. Если после первого выражения есть дополнительные символы, будет выброшена ошибка. Если raise
равно true
(по умолчанию), синтаксические ошибки вызовут ошибку; в противном случае parse
вернет выражение, которое вызовет ошибку при оценке. Если depwarn
равно false
, предупреждения о депрекации будут подавлены. Аргумент filename
используется для отображения диагностики, когда возникает ошибка.
julia> Meta.parse("x = 3")
:(x = 3)
julia> Meta.parse("1.0.2")
ERROR: ParseError:
# Error @ none:1:1
1.0.2
└──┘ ── недопустимая числовая константа
[...]
julia> Meta.parse("1.0.2"; raise = false)
:($(Expr(:error, "недопустимая числовая константа "1.0."")))
julia> Meta.parse("x = ")
:($(Expr(:incomplete, "недопустимо: преждевременный конец ввода")))
Base.Meta.ParseError
— TypeParseError(msg)
Выражение, переданное функции parse
, не может быть интерпретировано как допустимое выражение Julia.
Core.QuoteNode
— TypeQuoteNode
Цитируемый фрагмент кода, который не поддерживает интерполяцию. См. раздел руководства о QuoteNodes для получения подробной информации.
Base.macroexpand
— Functionmacroexpand(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.@macroexpand
— Macro@macroexpand [mod,] ex
Вернуть эквивалентное выражение с удаленными (развитыми) макросами. Если предоставлены два аргумента, первый - это модуль, в котором нужно выполнить оценку.
Существует разница между @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 (макрос с 1 методом)
julia> M.f()
(1, 1, 2)
С помощью @macroexpand
выражение разворачивается там, где появляется @macroexpand
в коде (модуль M
в примере). С помощью macroexpand
выражение разворачивается в модуле, указанном в качестве первого аргумента.
Форма с двумя аргументами требует как минимум Julia 1.11.
Base.@macroexpand1
— Macro@macroexpand1 [mod,] ex
Нерекурсивная версия @macroexpand
.
Base.code_lowered
— Functioncode_lowered(f, types; generated=true, debuginfo=:default)
Возвращает массив пониженных форм (IR) для методов, соответствующих данному обобщенному методу и сигнатуре типов.
Если generated
равно false
, возвращенные экземпляры CodeInfo
будут соответствовать запасным реализациям. Ошибка будет выброшена, если запасная реализация не существует. Если generated
равно true
, эти экземпляры CodeInfo
будут соответствовать телам методов, полученным в результате расширения генераторов.
Ключевое слово debuginfo
контролирует количество метаданных кода, присутствующих в выводе.
Обратите внимание, что ошибка будет выброшена, если types
не являются конечными типами, когда generated
равно true
, и любой из соответствующих методов является методом @generated
.
Base.code_typed
— Functioncode_typed(f, types; kw...)
Возвращает массив типа выведенной пониженнной формы (IR) для методов, соответствующих данному обобщенному методу и сигнатуре типов.
Ключевые Аргументы
optimize::Bool = true
: необязательный, управляет тем, применяются ли дополнительные оптимизации, такие как инлайнинг.debuginfo::Symbol = :default
: необязательный, управляет количеством метаданных кода, присутствующих в выводе, возможные варианты::source
или:none
.
Внутренние Ключевые Аргументы
Этот раздел следует считать внутренним и предназначен только для тех, кто понимает внутренности компилятора Julia.
world::UInt = Base.get_world_counter()
: необязательный, управляет возрастом мира, который используется при поиске методов, используйте текущий возраст мира, если не указано.interp::Core.Compiler.AbstractInterpreter = Core.Compiler.NativeInterpreter(world)
: необязательный, управляет абстрактным интерпретатором, который используется, используйте нативный интерпретатор, если не указано.
Примеры
Можно поместить типы аргументов в кортеж, чтобы получить соответствующий code_typed
.
julia> code_typed(+, (Float64, Float64))
1-element Vector{Any}:
CodeInfo(
1 ─ %1 = Base.add_float(x, y)::Float64
└── return %1
) => Float64
Base.precompile
— Functionprecompile(f, argtypes::Tuple{Vararg{Any}})
Скомпилируйте данную функцию f
для кортежа аргументов (типов) argtypes
, но не выполняйте её.
precompile(f, argtypes::Tuple{Vararg{Any}}, m::Method)
Предкомпилируйте конкретный метод для заданных типов аргументов. Это может быть использовано для предкомпиляции другого метода, чем тот, который обычно выбирается диспетчером, тем самым имитируя invoke
.
Base.jit_total_bytes
— FunctionBase.jit_total_bytes()
Возвращает общее количество (в байтах), выделенное компилятором с использованием Just-In-Time для, например, нативного кода и данных.
Meta
Base.Meta.quot
— FunctionMeta.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.isexpr
— FunctionMeta.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.isidentifier
— Function isidentifier(s) -> Bool
Возвращает, содержит ли символ или строка s
символы, которые интерпретируются как допустимый обычный идентификатор (не бинарный/унарный оператор) в коде Julia; см. также Base.isoperator
.
Внутри Julia разрешает любую последовательность символов в Symbol
(за исключением \0
s), и макросы автоматически используют имена переменных, содержащие #
, чтобы избежать конфликтов имен с окружающим кодом. Чтобы парсер мог распознать переменную, он использует ограниченный набор символов (значительно расширенный за счет Unicode). isidentifier()
позволяет напрямую запрашивать у парсера, содержит ли символ допустимые символы.
Примеры
julia> Meta.isidentifier(:x), Meta.isidentifier("1x")
(true, false)
Base.isoperator
— Functionisoperator(s::Symbol)
Возвращает true
, если символ может быть использован как оператор, false
в противном случае.
Примеры
julia> Meta.isoperator(:+), Meta.isoperator(:f)
(true, false)
Base.isunaryoperator
— Functionisunaryoperator(s::Symbol)
Возвращает true
, если символ может использоваться как унарный (префиксный) оператор, false
в противном случае.
Примеры
julia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f)
(true, true, false)
Base.isbinaryoperator
— Functionisbinaryoperator(s::Symbol)
Возвращает true
, если символ может быть использован как бинарный (инфиксный) оператор, false
в противном случае.
Примеры
julia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f)
(true, false, false)
Base.Meta.show_sexpr
— FunctionMeta.show_sexpr([io::IO,], ex)
Показать выражение ex
в стиле S-выражения Lisp.
Примеры
julia> Meta.show_sexpr(:(f(x, g(y,z))))
(:call, :f, :x, (:call, :g, :y, :z))