Essentials
Introduction
Julia Base contiene una variedad de funciones y macros apropiadas para realizar cálculos científicos y numéricos, pero también es tan amplia como la de muchos lenguajes de programación de propósito general. Funcionalidad adicional está disponible a partir de una colección en crecimiento de available packages. Las funciones están agrupadas por tema a continuación.
Algunas notas generales:
- Para usar las funciones del módulo, utiliza
import Module
para importar el módulo, yModule.fn(x)
para usar las funciones. - Alternativamente,
using Module
importará todas las funciones exportadas deModule
en el espacio de nombres actual. - Por convención, los nombres de las funciones que terminan con un signo de exclamación (
!
) modifican sus argumentos. Algunas funciones tienen versiones tanto modificadoras (por ejemplo,sort!
) como no modificadoras (sort
).
El comportamiento de Base
y las bibliotecas estándar son estables según lo definido en SemVer solo si están documentados; es decir, incluidos en el Julia documentation y no marcados como inestables. Consulte API FAQ para más información.
Getting Around
Base.exit
— Functionexit(code=0)
Detiene el programa con un código de salida. El código de salida predeterminado es cero, lo que indica que el programa se completó con éxito. En una sesión interactiva, exit()
se puede llamar con el atajo de teclado ^D
.
Base.atexit
— Functionatexit(f)
Registra una función de cero o un argumento f()
que se llamará al salir del proceso. Los ganchos de atexit()
se llaman en orden de último en entrar, primero en salir (LIFO) y se ejecutan antes de los finalizadores de objetos.
Si f
tiene un método definido para un argumento entero, se llamará como f(n::Int32)
, donde n
es el código de salida actual; de lo contrario, se llamará como f()
.
La forma de un argumento requiere Julia 1.9
Se permite que los ganchos de salida llamen a exit(n)
, en cuyo caso Julia saldrá con el código de salida n
(en lugar del código de salida original). Si más de un gancho de salida llama a exit(n)
, entonces Julia saldrá con el código de salida correspondiente al último gancho de salida llamado que llama a exit(n)
. (Debido a que los ganchos de salida se llaman en orden LIFO, "último llamado" es equivalente a "primero registrado".)
Nota: Una vez que se han llamado todos los ganchos de salida, no se pueden registrar más ganchos de salida, y cualquier llamada a atexit(f)
después de que todos los ganchos se hayan completado lanzará una excepción. Esta situación puede ocurrir si estás registrando ganchos de salida desde Tareas en segundo plano que aún pueden estar ejecutándose de manera concurrente durante el apagado.
Base.isinteractive
— Functionisinteractive() -> Bool
Determina si Julia está ejecutándose en una sesión interactiva.
Base.summarysize
— FunctionBase.summarysize(obj; exclude=Union{...}, chargeall=Union{...}) -> Int
Calcula la cantidad de memoria, en bytes, utilizada por todos los objetos únicos accesibles desde el argumento.
Argumentos Clave
exclude
: especifica los tipos de objetos a excluir de la travesía.chargeall
: especifica los tipos de objetos a los que siempre se les cobrará el tamaño de todos sus campos, incluso si esos campos normalmente serían excluidos.
Véase también sizeof
.
Ejemplos
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)
Especifica si el archivo que llama a esta función es precompilable, con un valor predeterminado de true
. Si un módulo o archivo no es seguro para la precompilación, debe llamar a __precompile__(false)
para lanzar un error si Julia intenta precompilarlo.
Base.include
— FunctionBase.include([mapexpr::Function,] m::Module, path::AbstractString)
Evalúa el contenido del archivo de origen de entrada en el ámbito global del módulo m
. Cada módulo (excepto aquellos definidos con baremodule
) tiene su propia definición de include
omitiendo el argumento m
, que evalúa el archivo en ese módulo. Devuelve el resultado de la última expresión evaluada del archivo de entrada. Durante la inclusión, se establece una ruta de inclusión local a la tarea en el directorio que contiene el archivo. Las llamadas anidadas a include
buscarán en relación con esa ruta. Esta función se utiliza típicamente para cargar código fuente de forma interactiva, o para combinar archivos en paquetes que están divididos en múltiples archivos de origen.
El primer argumento opcional mapexpr
se puede usar para transformar el código incluido antes de que se evalúe: para cada expresión analizada expr
en path
, la función include
en realidad evalúa mapexpr(expr)
. Si se omite, mapexpr
por defecto es identity
.
Se requiere Julia 1.5 para pasar el argumento mapexpr
.
include
— Functioninclude([mapexpr::Function,] path::AbstractString)
Evalúa el contenido del archivo de origen de entrada en el ámbito global del módulo que lo contiene. Cada módulo (excepto aquellos definidos con baremodule
) tiene su propia definición de include
, que evalúa el archivo en ese módulo. Devuelve el resultado de la última expresión evaluada del archivo de entrada. Durante la inclusión, se establece una ruta de inclusión local a la tarea en el directorio que contiene el archivo. Las llamadas anidadas a include
buscarán en relación con esa ruta. Esta función se utiliza típicamente para cargar código fuente de forma interactiva, o para combinar archivos en paquetes que están divididos en múltiples archivos de origen. El argumento path
se normaliza utilizando normpath
que resolverá los tokens de ruta relativa como ..
y convertirá /
en el separador de ruta apropiado.
El primer argumento opcional mapexpr
se puede usar para transformar el código incluido antes de que se evalúe: para cada expresión analizada expr
en path
, la función include
en realidad evalúa mapexpr(expr)
. Si se omite, mapexpr
por defecto es identity
.
Usa Base.include
para evaluar un archivo en otro módulo.
Se requiere Julia 1.5 para pasar el argumento mapexpr
.
Base.include_string
— Functioninclude_string([mapexpr::Function,] m::Module, code::AbstractString, filename::AbstractString="string")
Como include
, excepto que lee el código de la cadena dada en lugar de un archivo.
El primer argumento opcional mapexpr
se puede usar para transformar el código incluido antes de que se evalúe: para cada expresión analizada expr
en code
, la función include_string
evalúa en realidad mapexpr(expr)
. Si se omite, mapexpr
por defecto es identity
.
Se requiere Julia 1.5 para pasar el argumento mapexpr
.
Base.include_dependency
— Functioninclude_dependency(path::AbstractString; track_content::Bool=true)
En un módulo, declara que el archivo, directorio o enlace simbólico especificado por path
(relativo o absoluto) es una dependencia para la precompilación; es decir, si track_content=true
, el módulo necesitará ser recompilado si el contenido de path
cambia (si path
es un directorio, el contenido es igual a join(readdir(path))
). Si track_content=false
, la recompilación se activa cuando el tiempo de modificación mtime
de path
cambia.
Esto solo es necesario si tu módulo depende de una ruta que no se utiliza a través de include
. No tiene efecto fuera de la compilación.
El argumento clave track_content
requiere al menos Julia 1.11. Ahora se lanza un error si path
no es legible.
__init__
— Keyword__init__
La función __init__()
en un módulo se ejecuta inmediatamente después de que el módulo se carga en tiempo de ejecución por primera vez. Se llama una vez, después de que todas las demás declaraciones en el módulo han sido ejecutadas. Debido a que se llama después de importar completamente el módulo, las funciones __init__
de los submódulos se ejecutarán primero. Dos usos típicos de __init__
son llamar a funciones de inicialización en tiempo de ejecución de bibliotecas externas en C e inicializar constantes globales que involucran punteros devueltos por bibliotecas externas. Consulta la sección del manual sobre módulos para más detalles.
Ejemplos
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)
Devuelve el método de f
(un objeto Method
) que se llamaría para argumentos de los tipos dados types
.
Si types
es un tipo abstracto, se devuelve el método que sería llamado por invoke
.
Véase también: parentmodule
, @which
, y @edit
.
Base.methods
— Functionmethods(f, [types], [module])
Devuelve la tabla de métodos para f
.
Si se especifica types
, devuelve un array de métodos cuyas tipos coinciden. Si se especifica module
, devuelve un array de métodos definidos en ese módulo. También se puede especificar una lista de módulos como un array.
Se requiere al menos Julia 1.4 para especificar un módulo.
Véase también: which
, @which
y methodswith
.
Base.@show
— Macro@show exs...
Imprime una o más expresiones, y sus resultados, en stdout
, y devuelve el último resultado.
Véase también: show
, @info
, println
.
Ejemplos
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
Una variable que se refiere al último valor calculado, importada automáticamente al prompt interactivo.
Base.MainInclude.err
— Constanterr
Una variable que se refiere a los últimos errores lanzados, importada automáticamente al prompt interactivo. Los errores lanzados se recopilan en una pila de excepciones.
Base.active_project
— Functionactive_project()
Devuelve la ruta del archivo Project.toml
activo. Ver también Base.set_active_project
.
Base.set_active_project
— Functionset_active_project(projfile::Union{AbstractString,Nothing})
Establece el archivo Project.toml
activo a projfile
. Ver también Base.active_project
.
Esta función requiere al menos Julia 1.8.
Keywords
Esta es la lista de palabras clave reservadas en 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
. No se permite usar esas palabras clave como nombres de variables.
Las siguientes secuencias de dos palabras están reservadas: abstract type
, mutable struct
, primitive type
. Sin embargo, puedes crear variables con los nombres: abstract
, mutable
, primitive
y type
.
Finalmente: where
se analiza como un operador infijo para escribir definiciones de métodos y tipos paramétricos; in
e isa
se analizan como operadores infijos; public
se analiza como una palabra clave al comenzar una declaración de nivel superior; outer
se analiza como una palabra clave cuando se utiliza para modificar el alcance de una variable en una especificación de iteración de un bucle for
; y as
se utiliza como una palabra clave para renombrar un identificador traído al alcance por import
o using
. Sin embargo, se permite la creación de variables llamadas where
, in
, isa
, outer
y as
.
module
— Keywordmódulo
módulo
declara un Módulo
, que es un espacio de trabajo de variables globales separado. Dentro de un módulo, puedes controlar qué nombres de otros módulos son visibles (a través de la importación) y especificar cuáles de tus nombres están destinados a ser públicos (a través de export
y public
). Los módulos te permiten crear definiciones de nivel superior sin preocuparte por conflictos de nombres cuando tu código se utiliza junto con el de otra persona. Consulta la sección del manual sobre módulos para más detalles.
Ejemplos
módulo Foo
importar Base.show
exportar MyType, foo
estructura 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
se utiliza dentro de los módulos para indicar a Julia qué nombres deben estar disponibles para el usuario. Por ejemplo: export foo
hace que el nombre foo
esté disponible al usar
el módulo. Consulta la sección del manual sobre módulos para más detalles.
public
— Keywordpublic
public
se utiliza dentro de los módulos para indicar a Julia qué nombres son parte de la API pública del módulo. Por ejemplo: public foo
indica que el nombre foo
es público, sin hacerlo disponible al using
el módulo. Consulta la sección del manual sobre módulos para más detalles.
La palabra clave public se agregó en Julia 1.11. Antes de esto, la noción de publicidad era menos explícita.
import
— Keywordimport
import Foo
cargará el módulo o paquete Foo
. Los nombres del módulo Foo
importado se pueden acceder con la sintaxis de punto (por ejemplo, Foo.foo
para acceder al nombre foo
). Consulta la sección del manual sobre módulos para más detalles.
using
— Keywordusing
using Foo
cargará el módulo o paquete Foo
y hará que sus nombres export
ados estén disponibles para su uso directo. Los nombres también se pueden usar a través de la sintaxis de punto (por ejemplo, Foo.foo
para acceder al nombre foo
), ya sea que estén export
ados o no. Consulta la sección del manual sobre módulos para más detalles.
Cuando dos o más paquetes/módulos exportan un nombre y ese nombre no se refiere a lo mismo en cada uno de los paquetes, y los paquetes se cargan a través de using
sin una lista explícita de nombres, es un error hacer referencia a ese nombre sin calificación. Por lo tanto, se recomienda que el código destinado a ser compatible con versiones futuras de sus dependencias y de Julia, por ejemplo, el código en paquetes liberados, liste los nombres que utiliza de cada paquete cargado, por ejemplo, using Foo: Foo, f
en lugar de using Foo
.
as
— Keywordas
as
se utiliza como una palabra clave para renombrar un identificador traído al ámbito por import
o using
, con el propósito de evitar conflictos de nombres así como para acortar nombres. (Fuera de las declaraciones import
o using
, as
no es una palabra clave y puede ser utilizado como un identificador ordinario.)
import LinearAlgebra as LA
trae la biblioteca estándar LinearAlgebra
importada al ámbito como LA
.
import LinearAlgebra: eigen as eig, cholesky as chol
trae los métodos eigen
y cholesky
de LinearAlgebra
al ámbito como eig
y chol
respectivamente.
as
funciona con using
solo cuando se traen identificadores individuales al ámbito. Por ejemplo, using LinearAlgebra: eigen as eig
o using LinearAlgebra: eigen as eig, cholesky as chol
funciona, pero using LinearAlgebra as LA
es una sintaxis inválida, ya que no tiene sentido renombrar todos los nombres exportados de LinearAlgebra
a LA
.
baremodule
— Keywordbaremodule
baremodule
declara un módulo que no contiene using Base
ni definiciones locales de eval
y include
. Sin embargo, todavía importa Core
. En otras palabras,
module Mod
...
end
es equivalente a
baremodule Mod
using Base
eval(x) = Core.eval(Mod, x)
include(p) = Base.include(Mod, p)
...
end
function
— Keywordfunction
Las funciones se definen con la palabra clave function
:
function add(a, b)
return a + b
end
O la notación en forma corta:
add(a, b) = a + b
El uso de la palabra clave return
es exactamente el mismo que en otros lenguajes, pero a menudo es opcional. Una función sin una declaración return
explícita devolverá la última expresión en el cuerpo de la función.
macro
— Keywordmacro
macro
define un método para insertar código generado en un programa. Un macro mapea una secuencia de expresiones de argumento a una expresión devuelta, y la expresión resultante se sustituye directamente en el programa en el punto donde se invoca el macro. Los macros son una forma de ejecutar código generado sin llamar a eval
, ya que el código generado simplemente se convierte en parte del programa circundante. Los argumentos de los macros pueden incluir expresiones, valores literales y símbolos. Los macros se pueden definir para un número variable de argumentos (varargs), pero no aceptan argumentos de palabra clave. Cada macro también recibe implícitamente los argumentos __source__
, que contiene el número de línea y el nombre del archivo desde el cual se llama al macro, y __module__
, que es el módulo en el que se expande el macro.
Consulta la sección del manual sobre Metaprogramación para obtener más información sobre cómo escribir un macro.
Ejemplos
julia> macro sayhello(name)
return :( println("Hello, ", $name, "!") )
end
@sayhello (macro with 1 method)
julia> @sayhello "Charlie"
Hello, Charlie!
julia> macro saylots(x...)
return :( println("Say: ", $(x...)) )
end
@saylots (macro with 1 method)
julia> @saylots "hey " "there " "friend"
Say: hey there friend
return
— Keywordreturn
return x
hace que la función que lo contiene salga anticipadamente, pasando el valor dado x
de vuelta a su llamador. return
por sí solo sin un valor es equivalente a return nothing
(ver nothing
).
function compare(a, b)
a == b && return "equal to"
a < b ? "less than" : "greater than"
end
En general, puedes colocar una declaración return
en cualquier lugar dentro del cuerpo de una función, incluyendo dentro de bucles o condicionales profundamente anidados, pero ten cuidado con los bloques do
. Por ejemplo:
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
En el primer ejemplo, el return sale de test1
tan pronto como encuentra un número par, por lo que test1([5,6,7])
devuelve 12
.
Podrías esperar que el segundo ejemplo se comportara de la misma manera, pero de hecho el return
allí solo sale de la función interna (dentro del bloque do
) y devuelve un valor a map
. test2([5,6,7])
entonces devuelve [5,12,7]
.
Cuando se usa en una expresión de nivel superior (es decir, fuera de cualquier función), return
hace que toda la expresión de nivel superior actual termine anticipadamente.
do
— Keyworddo
Crea una función anónima y pásala como el primer argumento a una llamada de función. Por ejemplo:
map(1:10) do x
2x
end
es equivalente a map(x->2x, 1:10)
.
Usa múltiples argumentos de la siguiente manera:
map(1:10, 11:20) do x, y
x + y
end
begin
— Keywordbegin
begin...end
denota un bloque de código.
begin
println("Hola, ")
println("¡Mundo!")
end
Usualmente begin
no será necesario, ya que palabras clave como function
y let
comienzan implícitamente bloques de código. Ver también ;
.
begin
también puede ser utilizado al indexar para representar el primer índice de una colección o el primer índice de una dimensión de un arreglo. Por ejemplo, a[begin]
es el primer elemento de un arreglo a
.
El uso de begin
como un índice requiere Julia 1.4 o posterior.
Ejemplos
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
marca la conclusión de un bloque de expresiones, por ejemplo module
, struct
, mutable struct
, begin
, let
, for
etc.
end
también puede ser utilizado al indexar para representar el último índice de una colección o el último índice de una dimensión de un arreglo.
Ejemplos
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
Los bloques let
crean un nuevo ámbito rígido y, opcionalmente, introducen nuevos enlaces locales.
Al igual que los otros constructos de ámbito, los bloques let
definen el bloque de código donde las variables locales recién introducidas son accesibles. Además, la sintaxis tiene un significado especial para las asignaciones separadas por comas y los nombres de variables que pueden aparecer opcionalmente en la misma línea que el let
:
let var1 = value1, var2, var3 = value3
code
end
Las variables introducidas en esta línea son locales al bloque let
y las asignaciones se evalúan en orden, con cada lado derecho evaluado en el ámbito sin considerar el nombre en el lado izquierdo. Por lo tanto, tiene sentido escribir algo como let x = x
, ya que las dos variables x
son distintas, con el lado izquierdo ocultando localmente el x
del ámbito exterior. Esto puede ser incluso un modismo útil, ya que se crean nuevas variables locales cada vez que se ingresan ámbitos locales, pero esto solo es observable en el caso de variables que sobreviven a su ámbito a través de cierres. Una variable let
sin una asignación, como var2
en el ejemplo anterior, declara una nueva variable local que aún no está vinculada a un valor.
Por el contrario, los bloques begin
también agrupan múltiples expresiones, pero no introducen un ámbito ni tienen la sintaxis de asignación especial.
Ejemplos
En la función a continuación, hay un solo x
que se actualiza iterativamente tres veces por el map
. Los cierres devueltos hacen referencia a ese único x
en su valor final:
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
Sin embargo, si agregamos un bloque let
que introduce una nueva variable local, terminaremos con tres variables distintas siendo capturadas (una en cada iteración) a pesar de que elegimos usar (ocultar) el mismo nombre.
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
Todos los constructos de ámbito que introducen nuevas variables locales se comportan de esta manera cuando se ejecutan repetidamente; la característica distintiva de let
es su capacidad para declarar de manera sucinta nuevos local
s que pueden ocultar variables externas del mismo nombre. Por ejemplo, usar directamente el argumento de la función do
captura de manera similar tres variables distintas:
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
realiza una evaluación condicional, lo que permite que partes del código se evalúen o no se evalúen dependiendo del valor de una expresión booleana. Aquí está la anatomía de la sintaxis condicional if
/elseif
/else
:
if x < y
println("x es menor que y")
elseif x > y
println("x es mayor que y")
else
println("x es igual a y")
end
Si la expresión de condición x < y
es verdadera, entonces el bloque correspondiente se evalúa; de lo contrario, se evalúa la expresión de condición x > y
, y si es verdadera, se evalúa el bloque correspondiente; si ninguna de las expresiones es verdadera, se evalúa el bloque else
. Los bloques elseif
y else
son opcionales, y se pueden usar tantos bloques elseif
como se desee.
A diferencia de algunos otros lenguajes, las condiciones deben ser de tipo Bool
. No es suficiente que las condiciones sean convertibles a Bool
.
julia> if 1 end
ERROR: TypeError: non-boolean (Int64) used in boolean context
for
— Keywordfor
Los bucles for
evalúan repetidamente un bloque de declaraciones mientras iteran sobre una secuencia de valores.
La variable de iteración siempre es una nueva variable, incluso si existe una variable con el mismo nombre en el ámbito que la rodea. Usa outer
para reutilizar una variable local existente para la iteración.
Ejemplos
julia> for i in [1, 4, 0]
println(i)
end
1
4
0
while
— Keywordmientras
mientras
los bucles evalúan repetidamente una expresión condicional y continúan evaluando el cuerpo del bucle mientras la expresión siga siendo verdadera. Si la expresión de condición es falsa cuando se alcanza por primera vez el bucle mientras
, el cuerpo nunca se evalúa.
Ejemplos
julia> i = 1
1
julia> mientras i < 5
println(i)
global i += 1
end
1
2
3
4
break
— Keywordbreak
Salga de un bucle inmediatamente.
Ejemplos
julia> i = 0
0
julia> while true
global i += 1
i > 5 && break
println(i)
end
1
2
3
4
5
continue
— Keywordcontinue
Saltar la iteración actual del bucle.
Ejemplos
julia> for i = 1:6
iseven(i) && continue
println(i)
end
1
3
5
try
— Keywordtry/catch
Una declaración try
/catch
permite interceptar errores (excepciones) lanzados por throw
para que la ejecución del programa pueda continuar. Por ejemplo, el siguiente código intenta escribir un archivo, pero advierte al usuario y procede en lugar de terminar la ejecución si el archivo no se puede escribir:
try
open("/danger", "w") do f
println(f, "Hello")
end
catch
@warn "No se pudo escribir el archivo."
end
o, cuando el archivo no se puede leer en una variable:
lines = try
open("/danger", "r") do f
readlines(f)
end
catch
@warn "Archivo no encontrado."
end
La sintaxis catch e
(donde e
es cualquier variable) asigna el objeto de excepción lanzado a la variable dada dentro del bloque catch
.
El poder de la construcción try
/catch
radica en la capacidad de deshacer una computación profundamente anidada inmediatamente a un nivel mucho más alto en la pila de funciones llamadas.
finally
— Keywordfinalmente
Ejecuta algún código cuando un bloque de código dado sale, independientemente de cómo salga. Por ejemplo, aquí se muestra cómo podemos garantizar que un archivo abierto se cierre:
f = open("file")
try
operate_on_file(f)
finally
close(f)
end
Cuando el control sale del bloque try
(por ejemplo, debido a un return
, o simplemente finalizando normalmente), close(f)
se ejecutará. Si el bloque try
sale debido a una excepción, la excepción continuará propagándose. Un bloque catch
puede combinarse con try
y finally
también. En este caso, el bloque finally
se ejecutará después de que catch
haya manejado el error.
quote
— Keywordquote
quote
crea múltiples objetos de expresión en un bloque sin usar el constructor explícito Expr
. Por ejemplo:
ex = quote
x = 1
y = 2
x + y
end
A diferencia de otros medios de citar, :( ... )
, esta forma introduce elementos QuoteNode
en el árbol de expresiones, que deben ser considerados al manipular directamente el árbol. Para otros propósitos, :( ... )
y los bloques quote .. end
se tratan de manera idéntica.
local
— Keywordlocal
local
introduce una nueva variable local. Consulta la sección del manual sobre el alcance de las variables para más información.
Ejemplos
julia> function foo(n)
x = 0
for i = 1:n
local x # introduce un x local al bucle
x = i
end
x
end
foo (función genérica con 1 método)
julia> foo(10)
0
global
— Keywordglobal
global x
hace que x
en el ámbito actual y sus ámbitos internos se refiera a la variable global de ese nombre. Consulta la sección del manual sobre el alcance de las variables para más información.
Ejemplos
julia> z = 3
3
julia> function foo()
global z = 6 # usa la variable z definida fuera de foo
end
foo (función genérica con 1 método)
julia> foo()
6
julia> z
6
outer
— Keywordfor outer
Reutiliza una variable local existente para la iteración en un bucle for
.
Consulta la sección del manual sobre el alcance de las variables para más información.
Consulta también for
.
Ejemplos
julia> function f()
i = 0
for i = 1:3
# vacío
end
return i
end;
julia> f()
0
julia> function f()
i = 0
for outer i = 1:3
# vacío
end
return i
end;
julia> f()
3
julia> i = 0 # variable global
for outer i = 1:3
end
ERROR: syntax: no outer local variable declaration exists for "for outer"
[...]
const
— Keywordconst
const
se utiliza para declarar variables globales cuyos valores no cambiarán. En casi todo el código (y particularmente en el código sensible al rendimiento), las variables globales deben declararse constantes de esta manera.
const x = 5
Se pueden declarar múltiples variables dentro de un solo const
:
const y, z = 7, 11
Ten en cuenta que const
solo se aplica a una operación de =
; por lo tanto, const x = y = 1
declara x
como constante pero no y
. Por otro lado, const x = const y = 1
declara tanto x
como y
constantes.
Ten en cuenta que la "constancia" no se extiende a contenedores mutables; solo la asociación entre una variable y su valor es constante. Si x
es un arreglo o un diccionario (por ejemplo), aún puedes modificar, agregar o eliminar elementos.
En algunos casos, cambiar el valor de una variable const
da una advertencia en lugar de un error. Sin embargo, esto puede producir un comportamiento impredecible o corromper el estado de tu programa, por lo que debe evitarse. Esta característica está destinada solo para conveniencia durante el uso interactivo.
struct
— Keywordstruct
El tipo más comúnmente utilizado en Julia es un struct, especificado como un nombre y un conjunto de campos.
struct Point
x
y
end
Los campos pueden tener restricciones de tipo, que pueden ser parametrizadas:
struct Point{X}
x::X
y::Float64
end
Un struct también puede declarar un supertipo abstracto a través de la sintaxis <:
:
struct Point <: AbstractPoint
x
y
end
Los struct
s son inmutables por defecto; una instancia de uno de estos tipos no puede ser modificada después de su construcción. Usa mutable struct
en su lugar para declarar un tipo cuyas instancias pueden ser modificadas.
Consulta la sección del manual sobre Tipos Compuestos para más detalles, como cómo definir constructores.
mutable struct
— Keywordmutable struct
mutable struct
es similar a struct
, pero además permite que los campos del tipo se establezcan después de la construcción.
Los campos individuales de un mutable struct
pueden ser marcados como const
para hacerlos inmutables:
mutable struct Baz
a::Int
const b::Float64
end
La palabra clave const
para los campos de los mutable structs
requiere al menos Julia 1.8.
Consulta la sección del manual sobre Composite Types para más información.
Base.@kwdef
— Macro@kwdef typedef
Este es un macro auxiliar que define automáticamente un constructor basado en palabras clave para el tipo declarado en la expresión typedef
, que debe ser una expresión de struct
o mutable struct
. El argumento predeterminado se proporciona declarando campos de la forma field::T = default
o field = default
. Si no se proporciona un valor predeterminado, entonces el argumento de palabra clave se convierte en un argumento de palabra clave requerido en el constructor de tipo resultante.
Los constructores internos aún se pueden definir, pero al menos uno debe aceptar argumentos en la misma forma que el constructor interno predeterminado (es decir, un argumento posicional por campo) para funcionar correctamente con el constructor externo de palabras clave.
Base.@kwdef
para structs paramétricos y structs con supertipos requiere al menos Julia 1.1.
Este macro se exporta a partir de Julia 1.9.
Ejemplos
julia> @kwdef struct Foo
a::Int = 1 # valor predeterminado especificado
b::String # palabra clave requerida
end
Foo
julia> Foo(b="hi")
Foo(1, "hi")
julia> Foo()
ERROR: UndefKeywordError: argumento de palabra clave `b` no asignado
Stacktrace:
[...]
abstract type
— Keywordtipo abstracto
tipo abstracto
declara un tipo que no puede ser instanciado, y sirve solo como un nodo en el gráfico de tipos, describiendo así conjuntos de tipos concretos relacionados: aquellos tipos concretos que son sus descendientes. Los tipos abstractos forman la jerarquía conceptual que hace que el sistema de tipos de Julia sea más que solo una colección de implementaciones de objetos. Por ejemplo:
abstract type Number end
abstract type Real <: Number end
Number
no tiene supertipo, mientras que Real
es un subtipo abstracto de Number
.
primitive type
— Keywordtipo primitivo
tipo primitivo
declara un tipo concreto cuyos datos consisten únicamente en una serie de bits. Ejemplos clásicos de tipos primitivos son los enteros y los valores de punto flotante. Algunas declaraciones de tipos primitivos incorporados como ejemplo:
tipo primitivo Char 32 fin
tipo primitivo Bool <: Integer 8 fin
El número después del nombre indica cuántos bits de almacenamiento requiere el tipo. Actualmente, solo se admiten tamaños que son múltiplos de 8 bits. La declaración Bool
muestra cómo un tipo primitivo puede declararse opcionalmente como un subtipo de algún supertipo.
where
— Keyworddonde
La palabra clave where
crea un tipo UnionAll
, que puede considerarse como una unión iterada de otros tipos, sobre todos los valores de alguna variable. Por ejemplo, Vector{T} where T<:Real
incluye todos los Vector
s donde el tipo de elemento es algún tipo de número Real
.
El límite de la variable se establece de forma predeterminada en Any
si se omite:
Vector{T} where T # abreviatura de `where T<:Any`
Las variables también pueden tener límites inferiores:
Vector{T} where T>:Int
Vector{T} where Int<:T<:Real
También hay una sintaxis concisa para expresiones where
anidadas. Por ejemplo, esto:
Pair{T, S} where S<:Array{T} where T<:Number
se puede acortar a:
Pair{T, S} where {T<:Number, S<:Array{T}}
Esta forma se encuentra a menudo en las firmas de métodos.
Ten en cuenta que en esta forma, las variables se enumeran de afuera hacia adentro. Esto coincide con el orden en el que se sustituyen las variables cuando un tipo se "aplica" a valores de parámetros utilizando la sintaxis T{p1, p2, ...}
.
...
— KeywordEl operador "splat", `...`, representa una secuencia de argumentos. `...` se puede usar en definiciones de funciones, para indicar que la función acepta un número arbitrario de argumentos. `...` también se puede usar para aplicar una función a una secuencia de argumentos.
# Ejemplos
jldoctest 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;
;
tiene un papel similar en Julia que en muchos lenguajes similares a C, y se utiliza para delimitar el final de la declaración anterior.
;
no es necesario al final de una línea, pero se puede usar para separar declaraciones en una sola línea o para unir declaraciones en una sola expresión.
Agregar ;
al final de una línea en el REPL suprimirá la impresión del resultado de esa expresión.
En las declaraciones de funciones, y opcionalmente en las llamadas, ;
separa los argumentos regulares de las palabras clave.
En literales de arreglos, los argumentos separados por punto y coma tienen su contenido concatenado. Un separador hecho de un solo ;
concatena verticalmente (es decir, a lo largo de la primera dimensión), ;;
concatena horizontalmente (segunda dimensión), ;;;
concatena a lo largo de la tercera dimensión, etc. Tal separador también se puede usar en la última posición en los corchetes cuadrados para agregar dimensiones adicionales de longitud 1.
Un ;
en la primera posición dentro de paréntesis se puede usar para construir una tupla nombrada. La misma sintaxis (; ...)
en el lado izquierdo de una asignación permite la desestructuración de propiedades.
En el REPL estándar, escribir ;
en una línea vacía cambiará al modo shell.
Ejemplos
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) # sin el ; o una coma final esto asignaría a 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; # establecer variables b y x usando desestructuración de propiedades
julia> b, x
(2, 1)
julia> ; # al escribir ;, el aviso cambia (en su lugar) a: shell>
shell> echo hello
hello
=
— Keyword=
=
es el operador de asignación.
- Para la variable
a
y la expresiónb
,a = b
hace quea
se refiera al valor deb
. - Para funciones
f(x)
,f(x) = x
define una nueva constante de funciónf
, o agrega un nuevo método af
sif
ya está definido; este uso es equivalente afunction f(x); x; end
. a[i] = v
llama asetindex!
(a,v,i)
.a.b = c
llama asetproperty!
(a,:b,c)
.- Dentro de una llamada a función,
f(a=b)
pasab
como el valor del argumento de palabra clavea
. - Dentro de paréntesis con comas,
(a=1,)
construye unNamedTuple
.
Ejemplos
Asignar a
a b
no crea una copia de b
; en su lugar, usa copy
o 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
Las colecciones pasadas a funciones tampoco se copian. Las funciones pueden modificar (mutar) el contenido de los objetos a los que se refieren sus argumentos. (Los nombres de las funciones que hacen esto se les añade convencionalmente un sufijo '!'.)
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
La asignación puede operar en múltiples variables en paralelo, tomando valores de un iterable:
julia> a, b = 4, 5
(4, 5)
julia> a, b = 1:3
1:3
julia> a, b
(1, 2)
La asignación puede operar en múltiples variables en serie, y devolverá el valor de la expresión más a la derecha:
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])
La asignación en índices fuera de límites no hace crecer una colección. Si la colección es un Vector
se puede hacer crecer en su lugar con push!
o 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
Asignar []
no elimina elementos de una colección; en su lugar, usa 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
Forma corta para condicionales; se lee "si a
, evalúa b
de lo contrario evalúa c
". También conocido como el operador ternario.
Esta sintaxis es equivalente a if a; b else c end
, pero a menudo se utiliza para enfatizar el valor b
-o-c
que se está utilizando como parte de una expresión más grande, en lugar de los efectos secundarios que la evaluación de b
o c
puede tener.
Consulta la sección del manual sobre flujo de control para más detalles.
Ejemplos
julia> x = 1; y = 2;
julia> x > y ? println("x es mayor") : println("x no es mayor")
x no es mayor
julia> x > y ? "x es mayor" : x == y ? "x e y son iguales" : "y es mayor"
"y es mayor"
Standard Modules
Main
— ModuleMain
Main
es el módulo de nivel superior, y Julia comienza con Main
establecido como el módulo actual. Las variables definidas en el aviso van en Main
, y varinfo
lista las variables en Main
.
julia> @__MODULE__
Main
Core
— ModuleNúcleo
Núcleo
es el módulo que contiene todos los identificadores considerados "incorporados" al lenguaje, es decir, parte del lenguaje básico y no de bibliotecas. Cada módulo especifica implícitamente using Núcleo
, ya que no puedes hacer nada sin esas definiciones.
Base
— ModuleBase
La biblioteca base de Julia. Base
es un módulo que contiene funcionalidad básica (el contenido de base/
). Todos los módulos contienen implícitamente using Base
, ya que esto es necesario en la gran mayoría de los casos.
Base Submodules
Base.Broadcast
— ModuleBase.Broadcast
Módulo que contiene la implementación de la difusión.
Base.Docs
— ModuleDocs
El módulo Docs
proporciona el macro @doc
que se puede utilizar para establecer y recuperar metadatos de documentación para objetos de Julia.
Por favor, consulte la sección del manual sobre documentación para más información.
Base.Iterators
— ModuleMétodos para trabajar con Iteradores.
Base.Libc
— ModuleInterfaz a libc, la biblioteca estándar de C.
Base.Meta
— ModuleFunciones de conveniencia para metaprogramación.
Base.StackTraces
— ModuleHerramientas para recopilar y manipular trazas de pila. Principalmente utilizadas para construir errores.
Base.Sys
— ModuleProporcione métodos para recuperar información sobre el hardware y el sistema operativo.
Base.Threads
— ModuleSoporte de multihilo.
Base.GC
— ModuleBase.GC
Módulo con utilidades de recolección de basura.
All Objects
Core.:===
— Function===(x,y) -> Bool
≡(x,y) -> Bool
Determina si x
e y
son idénticos, en el sentido de que ningún programa podría distinguirlos. Primero se comparan los tipos de x
e y
. Si son idénticos, los objetos mutables se comparan por dirección en memoria y los objetos inmutables (como los números) se comparan por contenido a nivel de bits. Esta función a veces se llama "egal". Siempre devuelve un valor Bool
.
Ejemplos
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
Determina si x
es del tipo dado type
. También se puede usar como un operador infijo, por ejemplo, x isa type
.
Ejemplos
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
Similar a ==
, excepto por el tratamiento de números de punto flotante y de valores faltantes. isequal
trata todos los valores NaN
de punto flotante como iguales entre sí, trata -0.0
como desigual a 0.0
, y missing
como igual a missing
. Siempre devuelve un valor Bool
.
isequal
es una relación de equivalencia: es reflexiva (===
implica isequal
), simétrica (isequal(a, b)
implica isequal(b, a)
) y transitiva (isequal(a, b)
y isequal(b, c)
implica isequal(a, c)
).
Implementación
La implementación predeterminada de isequal
llama a ==
, por lo que un tipo que no involucra valores de punto flotante generalmente solo necesita definir ==
.
isequal
es la función de comparación utilizada por tablas hash (Dict
). isequal(x,y)
debe implicar que hash(x) == hash(y)
.
Esto significa que los tipos para los cuales existe un método personalizado ==
o isequal
deben implementar un método correspondiente hash
(y viceversa). Las colecciones generalmente implementan isequal
llamando a isequal
recursivamente en todos los contenidos.
Además, isequal
está vinculado con isless
, y trabajan juntos para definir un orden total fijo, donde exactamente uno de isequal(x, y)
, isless(x, y)
, o isless(y, x)
debe ser true
(y los otros dos false
).
Los tipos escalares generalmente no necesitan implementar isequal
por separado de ==
, a menos que representen números de punto flotante que sean susceptibles a una implementación más eficiente que la proporcionada como una alternativa genérica (basada en isnan
, signbit
, y ==
).
Ejemplos
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)
Crea una función que compara su argumento con x
utilizando isequal
, es decir, una función equivalente a y -> isequal(y, x)
.
La función devuelta es de tipo Base.Fix2{typeof(isequal)}
, que se puede utilizar para implementar métodos especializados.
Base.isless
— Functionisless(x, y)
Prueba si x
es menor que y
, de acuerdo con un orden total fijo (definido junto con isequal
). isless
no está definido para pares (x, y)
de todos los tipos. Sin embargo, si está definido, se espera que satisfaga lo siguiente:
- Si
isless(x, y)
está definido, entonces también lo estánisless(y, x)
yisequal(x, y)
, y exactamente uno de esos tres devuelvetrue
. - La relación definida por
isless
es transitiva, es decir,isless(x, y) && isless(y, z)
implicaisless(x, z)
.
Los valores que normalmente no tienen orden, como NaN
, se ordenan después de los valores regulares. Los valores missing
se ordenan al final.
Esta es la comparación predeterminada utilizada por sort!
.
Implementación
Los tipos no numéricos con un orden total deben implementar esta función. Los tipos numéricos solo necesitan implementarla si tienen valores especiales como NaN
. Los tipos con un orden parcial deben implementar <
. Consulta la documentación sobre Ordenamientos Alternativos para saber cómo definir métodos de ordenamiento alternativos que se pueden utilizar en funciones de ordenamiento y relacionadas.
Ejemplos
julia> isless(1, 3)
true
julia> isless("Red", "Blue")
false
Base.isunordered
— Functionisunordered(x)
Devuelve true
si x
es un valor que no se puede ordenar de acuerdo con <
, como NaN
o missing
.
Los valores que evalúan a true
con este predicado pueden ser ordenables con respecto a otros ordenamientos como isless
.
Esta función requiere Julia 1.7 o posterior.
Base.ifelse
— Functionifelse(condition::Bool, x, y)
Devuelve x
si condition
es true
, de lo contrario devuelve y
. Esto difiere de ?
o if
en que es una función ordinaria, por lo que todos los argumentos se evalúan primero. En algunos casos, usar ifelse
en lugar de una declaración if
puede eliminar la rama en el código generado y proporcionar un mayor rendimiento en bucles ajustados.
Ejemplos
julia> ifelse(1 > 2, 1, 2)
2
Core.typeassert
— Functiontypeassert(x, type)
Lanza un TypeError
a menos que x isa type
. La sintaxis x::type
llama a esta función.
Ejemplos
julia> typeassert(2.5, Int)
ERROR: TypeError: in typeassert, expected Int64, got a value of type Float64
Stacktrace:
[...]
Core.typeof
— Functiontypeof(x)
Obtén el tipo concreto de x
.
Consulta también eltype
.
Ejemplos
julia> a = 1//2;
julia> typeof(a)
Rational{Int64}
julia> M = [1 2; 3.5 4];
julia> typeof(M)
Matrix{Float64} (alias for Array{Float64, 2})
Core.tuple
— Functiontuple(xs...)
Construye una tupla de los objetos dados.
Véase también Tuple
, ntuple
, NamedTuple
.
Ejemplos
julia> tuple(1, 'b', pi)
(1, 'b', π)
julia> ans === (1, 'b', π)
true
julia> Tuple(Real[1, 2, pi]) # toma una colección
(1, 2, π)
Base.ntuple
— Functionntuple(f, n::Integer)
Crea una tupla de longitud n
, computando cada elemento como f(i)
, donde i
es el índice del elemento.
Ejemplos
julia> ntuple(i -> 2*i, 4)
(2, 4, 6, 8)
ntuple(f, ::Val{N})
Crea una tupla de longitud N
, calculando cada elemento como f(i)
, donde i
es el índice del elemento. Al tomar un argumento Val(N)
, es posible que esta versión de ntuple genere un código más eficiente que la versión que toma la longitud como un entero. Pero ntuple(f, N)
es preferible a ntuple(f, Val(N))
en casos donde N
no se puede determinar en tiempo de compilación.
Ejemplos
julia> ntuple(i -> 2*i, Val(4))
(2, 4, 6, 8)
Base.objectid
— Functionobjectid(x) -> UInt
Obtiene un valor hash para x
basado en la identidad del objeto.
Si x === y
entonces objectid(x) == objectid(y)
, y generalmente cuando x !== y
, objectid(x) != objectid(y)
.
Base.hash
— Functionhash(x[, h::UInt]) -> UInt
Calcula un código hash entero tal que isequal(x,y)
implica hash(x)==hash(y)
. El segundo argumento opcional h
es otro código hash que se mezcla con el resultado.
Los nuevos tipos deben implementar la forma de 2 argumentos, típicamente llamando al método hash
de 2 argumentos de forma recursiva para mezclar los hashes de los contenidos entre sí (y con h
). Típicamente, cualquier tipo que implemente hash
también debería implementar su propio ==
(de ahí isequal
) para garantizar la propiedad mencionada anteriormente.
El valor hash puede cambiar cuando se inicia un nuevo proceso de Julia.
julia> a = hash(10)
0x95ea2955abd45275
julia> hash(10, a) # solo usa la salida de otra función hash como segundo argumento
0xd42bad54a8575b16
Base.finalizer
— Functionfinalizer(f, x)
Registra una función f(x)
que se llamará cuando no haya referencias accesibles al programa para x
, y devuelve x
. El tipo de x
debe ser un mutable struct
, de lo contrario, la función lanzará una excepción.
f
no debe causar un cambio de tarea, lo que excluye la mayoría de las operaciones de E/S como println
. Usar el macro @async
(para diferir el cambio de contexto fuera del finalizador) o ccall
para invocar directamente funciones de E/S en C puede ser útil para fines de depuración.
Ten en cuenta que no hay una edad de mundo garantizada para la ejecución de f
. Puede ser llamada en la edad de mundo en la que se registró el finalizador o en cualquier edad de mundo posterior.
Ejemplos
finalizer(my_mutable_struct) do x
@async println("Finalizando $x.")
end
finalizer(my_mutable_struct) do x
ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizando %s.", repr(x))
end
Un finalizador puede ser registrado en la construcción del objeto. En el siguiente ejemplo, ten en cuenta que confiamos implícitamente en que el finalizador devuelve el mutable struct
recién creado x
.
mutable struct MyMutableStruct
bar
function MyMutableStruct(bar)
x = new(bar)
f(t) = @async println("Finalizando $t.")
finalizer(f, x)
end
end
Base.finalize
— Functionfinalize(x)
Ejecuta inmediatamente los finalizadores registrados para el objeto x
.
Base.copy
— Functioncopy(x)
Crea una copia superficial de x
: se copia la estructura externa, pero no todos los valores internos. Por ejemplo, copiar un arreglo produce un nuevo arreglo con elementos idénticos al original.
Base.deepcopy
— Functiondeepcopy(x)
Crea una copia profunda de x
: todo se copia recursivamente, resultando en un objeto completamente independiente. Por ejemplo, hacer una copia profunda de un arreglo crea copias profundas de todos los objetos que contiene y produce un nuevo arreglo con la estructura de relación consistente (por ejemplo, si los dos primeros elementos son el mismo objeto en el arreglo original, los dos primeros elementos del nuevo arreglo también serán el mismo objeto deepcopy
ed). Llamar a deepcopy
en un objeto debería tener generalmente el mismo efecto que serializar y luego deserializarlo.
Aunque normalmente no es necesario, los tipos definidos por el usuario pueden anular el comportamiento predeterminado de deepcopy
definiendo una versión especializada de la función deepcopy_internal(x::T, dict::IdDict)
(que no debería usarse de otra manera), donde T
es el tipo para el que se va a especializar, y dict
lleva un registro de los objetos copiados hasta ahora dentro de la recursión. Dentro de la definición, deepcopy_internal
debería usarse en lugar de deepcopy
, y la variable dict
debería actualizarse según sea apropiado antes de devolver.
Base.getproperty
— Functiongetproperty(value, name::Symbol)
getproperty(value, name::Symbol, order::Symbol)
La sintaxis a.b
llama a getproperty(a, :b)
. La sintaxis @atomic order a.b
llama a getproperty(a, :b, :order)
y la sintaxis @atomic a.b
llama a getproperty(a, :b, :sequentially_consistent)
.
Ejemplos
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
Uno debería sobrecargar getproperty
solo cuando sea necesario, ya que puede ser confuso si el comportamiento de la sintaxis obj.f
es inusual. También tenga en cuenta que usar métodos es a menudo preferible. Consulte también esta documentación de la guía de estilo para más información: Prefer exported methods over direct field access.
Consulte también getfield
, propertynames
y setproperty!
.
Base.setproperty!
— Functionsetproperty!(value, name::Symbol, x)
setproperty!(value, name::Symbol, x, order::Symbol)
La sintaxis a.b = c
llama a setproperty!(a, :b, c)
. La sintaxis @atomic order a.b = c
llama a setproperty!(a, :b, c, :order)
y la sintaxis @atomic a.b = c
llama a setproperty!(a, :b, c, :sequentially_consistent)
.
setproperty!
en módulos requiere al menos Julia 1.8.
Véase también setfield!
, propertynames
y getproperty
.
Base.replaceproperty!
— Functionreplaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)
Realiza una operación de comparación e intercambio en x.f
de expected
a desired
, según egal. La sintaxis @atomicreplace x.f expected => desired
se puede usar en lugar de la forma de llamada a la función.
Véase también replacefield!
setproperty!
, setpropertyonce!
.
Base.swapproperty!
— Functionswapproperty!(x, f::Symbol, v, order::Symbol=:not_atomic)
La sintaxis @atomic a.b, _ = c, a.b
devuelve (c, swapproperty!(a, :b, c, :sequentially_consistent))
, donde debe haber una expresión getproperty
común a ambos lados.
Véase también swapfield!
y setproperty!
.
Base.modifyproperty!
— Functionmodifyproperty!(x, f::Symbol, op, v, order::Symbol=:not_atomic)
La sintaxis @atomic op(x.f, v)
(y su equivalente @atomic x.f op v
) devuelve modifyproperty!(x, :f, op, v, :sequentially_consistent)
, donde el primer argumento debe ser una expresión getproperty
y se modifica de manera atómica.
La invocación de op(getproperty(x, f), v)
debe devolver un valor que se pueda almacenar en el campo f
del objeto x
por defecto. En particular, a diferencia del comportamiento predeterminado de setproperty!
, la función convert
no se llama automáticamente.
Véase también modifyfield!
y setproperty!
.
Base.setpropertyonce!
— Functionsetpropertyonce!(x, f::Symbol, value, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)
Realiza una operación de comparación e intercambio en x.f
para establecerlo en value
si anteriormente no estaba establecido. La sintaxis @atomiconce x.f = value
se puede usar en lugar de la forma de llamada a la función.
Véase también setfieldonce!
, setproperty!
, replaceproperty!
.
Esta función requiere Julia 1.11 o posterior.
Base.propertynames
— Functionpropertynames(x, private=false)
Obtiene una tupla o un vector de las propiedades (x.property
) de un objeto x
. Esto es típicamente lo mismo que fieldnames(typeof(x))
, pero los tipos que sobrecargan getproperty
generalmente deberían sobrecargar propertynames
también para obtener las propiedades de una instancia del tipo.
propertynames(x)
puede devolver solo los nombres de propiedades "públicas" que son parte de la interfaz documentada de x
. Si deseas que también devuelva los nombres de propiedades "privadas" destinadas para uso interno, pasa true
como segundo argumento opcional. La finalización de tabulación en el REPL sobre x.
muestra solo las propiedades private=false
.
Consulta también: hasproperty
, hasfield
.
Base.hasproperty
— Functionhasproperty(x, s::Symbol)
Devuelve un booleano que indica si el objeto x
tiene s
como una de sus propias propiedades.
Esta función requiere al menos Julia 1.2.
Véase también: propertynames
, hasfield
.
Core.getfield
— Functiongetfield(value, name::Symbol, [order::Symbol])
getfield(value, i::Int, [order::Symbol])
Extrae un campo de un value
compuesto por nombre o posición. Opcionalmente, se puede definir un orden para la operación. Si el campo fue declarado @atomic
, se recomienda encarecidamente que la especificación sea compatible con los almacenes en esa ubicación. De lo contrario, si no se declara como @atomic
, este parámetro debe ser :not_atomic
si se especifica. Ver también getproperty
y fieldnames
.
Ejemplos
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])
Asigna x
a un campo nombrado en value
de tipo compuesto. El value
debe ser mutable y x
debe ser un subtipo de fieldtype(typeof(value), name)
. Además, se puede especificar un orden para esta operación. Si el campo fue declarado @atomic
, esta especificación es obligatoria. De lo contrario, si no se declara como @atomic
, debe ser :not_atomic
si se especifica. Véase también setproperty!
.
Ejemplos
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
Realiza de manera atómica las operaciones para obtener y establecer un campo después de aplicar la función op
.
y = getfield(value, name)
z = op(y, x)
setfield!(value, name, z)
return y => z
Si es compatible con el hardware (por ejemplo, incremento atómico), esto puede optimizarse a la instrucción de hardware apropiada; de lo contrario, utilizará un bucle.
Esta función requiere Julia 1.7 o posterior.
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)
Realiza atómicamente las operaciones para obtener y condicionalmente establecer un campo a un valor dado.
y = getfield(value, name, fail_order)
ok = y === expected
if ok
setfield!(value, name, desired, success_order)
end
return (; old = y, success = ok)
Si es compatible con el hardware, esto puede optimizarse a la instrucción de hardware apropiada; de lo contrario, utilizará un bucle.
Esta función requiere Julia 1.7 o posterior.
Core.swapfield!
— Functionswapfield!(value, name::Symbol, x, [order::Symbol])
swapfield!(value, i::Int, x, [order::Symbol])
Realiza atómicamente las operaciones para obtener y establecer simultáneamente un campo:
y = getfield(value, name)
setfield!(value, name, x)
return y
Esta función requiere Julia 1.7 o posterior.
Core.setfieldonce!
— Functionsetfieldonce!(value, name::Union{Int,Symbol}, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool
Realiza atómicamente las operaciones para establecer un campo a un valor dado, solo si no se había establecido previamente.
ok = !isdefined(value, name, fail_order)
if ok
setfield!(value, name, desired, success_order)
end
return ok
Esta función requiere Julia 1.11 o posterior.
Core.isdefined
— Functionisdefined(m::Module, s::Symbol, [order::Symbol])
isdefined(object, s::Symbol, [order::Symbol])
isdefined(object, index::Int, [order::Symbol])
Prueba si una variable global o un campo de objeto está definido. Los argumentos pueden ser un módulo y un símbolo o un objeto compuesto y el nombre del campo (como un símbolo) o índice. Opcionalmente, se puede definir un orden para la operación. Si el campo fue declarado @atomic
, se recomienda encarecidamente que la especificación sea compatible con las asignaciones a esa ubicación. De lo contrario, si no se declara como @atomic
, este parámetro debe ser :not_atomic
si se especifica.
Para probar si un elemento de un arreglo está definido, utiliza isassigned
en su lugar.
Ver también @isdefined
.
Ejemplos
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
Prueba si la variable s
está definida en el ámbito actual.
Consulta también isdefined
para propiedades de campo y isassigned
para índices de matriz o haskey
para otros mapeos.
Ejemplos
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)
Convierte x
a un valor del tipo T
.
Si T
es un tipo de Integer
, se generará un InexactError
si x
no es representable por T
, por ejemplo, si x
no es un valor entero, o está fuera del rango soportado por T
.
Ejemplos
julia> convert(Int, 3.0)
3
julia> convert(Int, 3.5)
ERROR: InexactError: Int64(3.5)
Stacktrace:
[...]
Si T
es un tipo de AbstractFloat
, entonces devolverá el valor más cercano a x
representable por T
. Inf se trata como una ulp mayor que floatmax(T)
para fines de determinación del más cercano.
julia> x = 1/3
0.3333333333333333
julia> convert(Float32, x)
0.33333334f0
julia> convert(BigFloat, x)
0.333333333333333314829616256247390992939472198486328125
Si T
es un tipo de colección y x
es una colección, el resultado de convert(T, x)
puede hacer referencia a todo o parte de x
.
julia> x = Int[1, 2, 3];
julia> y = convert(Vector{Int}, x);
julia> y === x
true
Ver también: round
, trunc
, oftype
, reinterpret
.
Base.promote
— Functionpromote(xs...)
Convierte todos los argumentos a un tipo común y los devuelve todos (como una tupla). Si no se pueden convertir argumentos, se genera un error.
Véase también: promote_type
, promote_rule
.
Ejemplos
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: la promoción de tipos Int64 y String no pudo cambiar ningún argumento
[...]
julia> promote_type(Int, String)
Any
Base.oftype
— Functionoftype(x, y)
Convierte y
al tipo de x
, es decir, convert(typeof(x), y)
.
Ejemplos
julia> x = 4;
julia> y = 3.;
julia> oftype(x, y)
3
julia> oftype(y, x)
4.0
Base.widen
— Functionwiden(x)
Si x
es un tipo, devuelve un tipo "más grande", definido de tal manera que las operaciones aritméticas +
y -
están garantizadas de no desbordarse ni perder precisión para cualquier combinación de valores que el tipo x
puede contener.
Para tipos de enteros de tamaño fijo menores de 128 bits, widen
devolverá un tipo con el doble de bits.
Si x
es un valor, se convierte a widen(typeof(x))
.
Ejemplos
julia> widen(Int32)
Int64
julia> widen(1.5f0)
1.5
Base.identity
— Functionidentity(x)
La función identidad. Devuelve su argumento.
Véase también: one
, oneunit
, y I
de LinearAlgebra
.
Ejemplos
julia> identity("Well, what did you expect?")
"Well, what did you expect?"
Core.WeakRef
— TypeWeakRef(x)
w = WeakRef(x)
construye una referencia débil al valor de Julia x
: aunque w
contiene una referencia a x
, no impide que x
sea recolectado por el recolector de basura. w.value
es x
(si x
no ha sido recolectado por el recolector de basura aún) o nothing
(si x
ha sido recolectado por el recolector de basura).
julia> x = "a string"
"a string"
julia> w = WeakRef(x)
WeakRef("a string")
julia> GC.gc()
julia> w # se mantiene una referencia a través de `x`
WeakRef("a string")
julia> x = nothing # limpiar referencia
julia> GC.gc()
julia> w
WeakRef(nothing)
Properties of Types
Type relations
Base.supertype
— Functionsupertype(T::DataType)
Devuelve el supertipo del tipo de dato T
.
Ejemplos
julia> supertype(Int32)
Signed
Core.Type
— TypeCore.Type{T}
Core.Type
es un tipo abstracto que tiene todos los objetos de tipo como sus instancias. La única instancia del tipo singleton Core.Type{T}
es el objeto T
.
Ejemplos
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
representa tipos declarados explícitamente que tienen nombres, supertipos declarados explícitamente y, opcionalmente, parámetros. Cada valor concreto en el sistema es una instancia de algún DataType
.
Ejemplos
julia> typeof(Real)
DataType
julia> typeof(Int)
DataType
julia> struct Point
x::Int
y
end
julia> typeof(Point)
DataType
Core.:<:
— Function<:(T1, T2)
Operador de subtipo: devuelve true
si y solo si todos los valores del tipo T1
también son del tipo T2
.
Ejemplos
julia> Float64 <: AbstractFloat
true
julia> Vector{Int} <: AbstractArray
true
julia> Matrix{Float64} <: Matrix{AbstractFloat}
false
Base.:>:
— Function>:(T1, T2)
Operador de supertipo, equivalente a T2 <: T1
.
Base.typejoin
— Functiontypejoin(T, S, ...)
Devuelve el ancestro común más cercano de los tipos T
y S
, es decir, el tipo más estrecho del cual ambos heredan. Recurre en argumentos adicionales.
Ejemplos
julia> typejoin(Int, Float64)
Real
julia> typejoin(Int, Float64, ComplexF32)
Number
Base.typeintersect
— Functiontypeintersect(T::Type, S::Type)
Calcula un tipo que contiene la intersección de T
y S
. Normalmente, este será el tipo más pequeño o uno cercano a él.
Un caso especial donde se garantiza un comportamiento exacto: cuando T <: S
, typeintersect(S, T) == T == typeintersect(T, S)
.
Base.promote_type
— Functionpromote_type(type1, type2, ...)
La promoción se refiere a convertir valores de tipos mixtos a un único tipo común. promote_type
representa el comportamiento de promoción predeterminado en Julia cuando los operadores (generalmente matemáticos) reciben argumentos de tipos diferentes. promote_type
generalmente intenta devolver un tipo que al menos pueda aproximar la mayoría de los valores de cualquiera de los tipos de entrada sin ampliar excesivamente. Se tolera cierta pérdida; por ejemplo, promote_type(Int64, Float64)
devuelve Float64
aunque estrictamente, no todos los valores de Int64
pueden ser representados exactamente como valores de Float64
.
Véase también: promote
, promote_typejoin
, promote_rule
.
Ejemplos
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
Para sobrecargar la promoción para tus propios tipos, debes sobrecargar promote_rule
. promote_type
llama a promote_rule
internamente para determinar el tipo. Sobrecargar promote_type
directamente puede causar errores de ambigüedad.
Base.promote_rule
— Functionpromote_rule(type1, type2)
Especifica qué tipo debe ser utilizado por promote
cuando se le dan valores de los tipos type1
y type2
. Esta función no debe ser llamada directamente, sino que se deben agregar definiciones a ella para nuevos tipos según sea apropiado.
Base.promote_typejoin
— Functionpromote_typejoin(T, S)
Calcula un tipo que contiene tanto T
como S
, que podría ser un padre de ambos tipos, o un Union
si es apropiado. Recurre a typejoin
.
Ver también promote
, promote_type
.
Ejemplos
julia> Base.promote_typejoin(Int, Float64)
Real
julia> Base.promote_type(Int, Float64)
Float64
Base.isdispatchtuple
— Functionisdispatchtuple(T)
Determina si el tipo T
es un "tipo hoja de tupla", lo que significa que podría aparecer como una firma de tipo en la dispatch y no tiene subtipos (o supertipos) que podrían aparecer en una llamada. Si T
no es un tipo, entonces devuelve false
.
Declared structure
Base.ismutable
— Functionismutable(v) -> Bool
Devuelve true
si y solo si el valor v
es mutable. Consulta Tipos Compuestos Mutables para una discusión sobre la inmutabilidad. Ten en cuenta que esta función trabaja con valores, por lo que si le das un DataType
, te dirá que un valor del tipo es mutable.
Por razones técnicas, ismutable
devuelve true
para valores de ciertos tipos especiales (por ejemplo String
y Symbol
) aunque no se puedan mutar de una manera permisible.
Consulta también isbits
, isstructtype
.
Ejemplos
julia> ismutable(1)
false
julia> ismutable([1,2])
true
Esta función requiere al menos Julia 1.5.
Base.isimmutable
— Functionisimmutable(v) -> Bool
Considera usar !ismutable(v)
en su lugar, ya que isimmutable(v)
será reemplazado por !ismutable(v)
en una futura versión. (Desde Julia 1.5)
Devuelve true
si y solo si el valor v
es inmutable. Consulta Tipos Compuestos Mutables para una discusión sobre la inmutabilidad. Ten en cuenta que esta función trabaja con valores, por lo que si le das un tipo, te dirá que un valor de DataType
es mutable.
Ejemplos
julia> isimmutable(1)
true
julia> isimmutable([1,2])
false
Base.ismutabletype
— Functionismutabletype(T) -> Bool
Determina si el tipo T
fue declarado como un tipo mutable (es decir, utilizando la palabra clave mutable struct
). Si T
no es un tipo, entonces devuelve false
.
Esta función requiere al menos Julia 1.7.
Base.isabstracttype
— Functionisabstracttype(T)
Determina si el tipo T
fue declarado como un tipo abstracto (es decir, utilizando la sintaxis abstract type
). Ten en cuenta que esto no es la negación de isconcretetype(T)
. Si T
no es un tipo, entonces devuelve false
.
Ejemplos
julia> isabstracttype(AbstractArray)
true
julia> isabstracttype(Vector)
false
Base.isprimitivetype
— Functionisprimitivetype(T) -> Bool
Determina si el tipo T
fue declarado como un tipo primitivo (es decir, utilizando la sintaxis primitive type
). Si T
no es un tipo, entonces devuelve false
.
Base.issingletontype
— FunctionBase.issingletontype(T)
Determina si el tipo T
tiene exactamente una posible instancia; por ejemplo, un tipo de estructura sin campos excepto otros valores singleton. Si T
no es un tipo concreto, entonces devuelve false
.
Base.isstructtype
— Functionisstructtype(T) -> Bool
Determina si el tipo T
fue declarado como un tipo de estructura (es decir, utilizando la palabra clave struct
o mutable struct
). Si T
no es un tipo, entonces devuelve false
.
Base.nameof
— Methodnameof(t::DataType) -> Symbol
Obtiene el nombre de un DataType
(potencialmente envuelto en UnionAll
) (sin su módulo padre) como un símbolo.
Ejemplos
julia> module Foo
struct S{T}
end
end
Foo
julia> nameof(Foo.S{T} where T)
:S
Base.fieldnames
— Functionfieldnames(x::DataType)
Obtiene una tupla con los nombres de los campos de un DataType
.
Véase también propertynames
, hasfield
.
Ejemplos
julia> fieldnames(Rational)
(:num, :den)
julia> fieldnames(typeof(1+im))
(:re, :im)
Base.fieldname
— Functionfieldname(x::DataType, i::Integer)
Obtiene el nombre del campo i
de un DataType
.
Ejemplos
julia> fieldname(Rational, 1)
:num
julia> fieldname(Rational, 2)
:den
Core.fieldtype
— Functionfieldtype(T, name::Symbol | index::Int)
Determina el tipo declarado de un campo (especificado por nombre o índice) en un tipo de dato compuesto T
.
Ejemplos
julia> struct Foo
x::Int64
y::String
end
julia> fieldtype(Foo, :x)
Int64
julia> fieldtype(Foo, 2)
String
Base.fieldtypes
— Functionfieldtypes(T::Type)
Los tipos declarados de todos los campos en un DataType compuesto T
como una tupla.
Esta función requiere al menos Julia 1.1.
Ejemplos
julia> struct Foo
x::Int64
y::String
end
julia> fieldtypes(Foo)
(Int64, String)
Base.fieldcount
— Functionfieldcount(t::Type)
Obtiene el número de campos que tendría una instancia del tipo dado. Se lanza un error si el tipo es demasiado abstracto para determinar esto.
Base.hasfield
— Functionhasfield(T::Type, name::Symbol)
Devuelve un booleano que indica si T
tiene name
como uno de sus propios campos.
Véase también fieldnames
, fieldcount
, hasproperty
.
Esta función requiere al menos Julia 1.2.
Ejemplos
julia> struct Foo
bar::Int
end
julia> hasfield(Foo, :bar)
true
julia> hasfield(Foo, :x)
false
Core.nfields
— Functionnfields(x) -> Int
Obtiene el número de campos en el objeto dado.
Ejemplos
julia> a = 1//2;
julia> nfields(a)
2
julia> b = 1
1
julia> nfields(b)
0
julia> ex = ErrorException("He hecho algo malo");
julia> nfields(ex)
1
En estos ejemplos, a
es un Rational
, que tiene dos campos. b
es un Int
, que es un tipo de bit primitivo sin campos en absoluto. ex
es un ErrorException
, que tiene un campo.
Base.isconst
— Functionisconst(m::Module, s::Symbol) -> Bool
Determina si una variable global está declarada como const
en un módulo dado m
.
isconst(t::DataType, s::Union{Int,Symbol}) -> Bool
Determina si un campo s
está declarado como const
en un tipo dado t
.
Base.isfieldatomic
— Functionisfieldatomic(t::DataType, s::Union{Int,Symbol}) -> Bool
Determina si un campo s
está declarado @atomic
en un tipo dado t
.
Memory layout
Base.sizeof
— Methodsizeof(T::DataType)
sizeof(obj)
Tamaño, en bytes, de la representación binaria canónica del DataType
dado T
, si existe. O el tamaño, en bytes, del objeto obj
si no es un DataType
.
Véase también Base.summarysize
.
Ejemplos
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) # no es la suma de `sizeof` de los campos debido al relleno
16
julia> sizeof(Int64) + sizeof(Bool) # diferente de arriba
9
Si el DataType
T
no tiene un tamaño específico, se lanza un error.
julia> sizeof(AbstractArray)
ERROR: El tipo abstracto AbstractArray no tiene un tamaño definido.
Stacktrace:
[...]
Base.isconcretetype
— Functionisconcretetype(T)
Determina si el tipo T
es un tipo concreto, lo que significa que podría tener instancias directas (valores x
tales que typeof(x) === T
). Ten en cuenta que esto no es la negación de isabstracttype(T)
. Si T
no es un tipo, entonces devuelve false
.
Ver también: isbits
, isabstracttype
, issingletontype
.
Ejemplos
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)
Devuelve true
si x
es una instancia de un tipo isbitstype
.
Base.isbitstype
— Functionisbitstype(T)
Devuelve true
si el tipo T
es un tipo de "datos simples", lo que significa que es inmutable y no contiene referencias a otros valores, solo tipos primitivos
y otros tipos isbitstype
. Ejemplos típicos son tipos numéricos como UInt8
, Float64
y Complex{Float64}
. Esta categoría de tipos es significativa ya que son válidos como parámetros de tipo, pueden no rastrear el estado de isdefined
/ isassigned
, y tienen un diseño definido que es compatible con C. Si T
no es un tipo, entonces devuelve false
.
Véase también isbits
, isprimitivetype
, ismutable
.
Ejemplos
julia> isbitstype(Complex{Float64})
true
julia> isbitstype(Complex)
false
Base.fieldoffset
— Functionfieldoffset(tipo, i)
El desplazamiento en bytes del campo i
de un tipo en relación con el inicio de los datos. Por ejemplo, podríamos usarlo de la siguiente manera para resumir información sobre una estructura:
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
Alineación mínima de la asignación de memoria para instancias de este tipo. Se puede llamar en cualquier isconcretetype
, aunque para Memory dará la alineación de los elementos, no del objeto completo.
Base.datatype_haspadding
— FunctionBase.datatype_haspadding(dt::DataType) -> Bool
Devuelve si los campos de las instancias de este tipo están empaquetados en memoria, sin bits de relleno intermedios (definidos como bits cuyo valor no impacta de manera única en la prueba de igualdad cuando se aplica a los campos de la estructura). Se puede llamar a cualquier isconcretetype
.
Base.datatype_pointerfree
— FunctionBase.datatype_pointerfree(dt::DataType) -> Bool
Devuelve si las instancias de este tipo pueden contener referencias a memoria gestionada por el recolector de basura. Se puede llamar en cualquier isconcretetype
.
Special values
Base.typemin
— Functiontypemin(T)
El valor más bajo que se puede representar con el tipo de dato numérico (real) dado T
.
Véase también: floatmin
, typemax
, eps
.
Ejemplos
julia> typemin(Int8)
-128
julia> typemin(UInt32)
0x00000000
julia> typemin(Float16)
-Inf16
julia> typemin(Float32)
-Inf32
julia> nextfloat(-Inf32) # el número de punto flotante Float32 finito más pequeño
-3.4028235f38
Base.typemax
— Functiontypemax(T)
El valor más alto que se puede representar con el DataType
numérico (real) dado.
Véase también: floatmax
, typemin
, eps
.
Ejemplos
julia> typemax(Int8)
127
julia> typemax(UInt32)
0xffffffff
julia> typemax(Float64)
Inf
julia> typemax(Float32)
Inf32
julia> floatmax(Float32) # el número de punto flotante Finito más grande de Float32
3.4028235f38
Base.floatmin
— Functionfloatmin(T = Float64)
Devuelve el número normal positivo más pequeño que se puede representar con el tipo de punto flotante T
.
Ejemplos
julia> floatmin(Float16)
Float16(6.104e-5)
julia> floatmin(Float32)
1.1754944f-38
julia> floatmin()
2.2250738585072014e-308
Base.floatmax
— Functionfloatmax(T = Float64)
Devuelve el número finito más grande que se puede representar con el tipo de punto flotante T
.
Véase también: typemax
, floatmin
, eps
.
Ejemplos
julia> floatmax(Float16)
Float16(6.55e4)
julia> floatmax(Float32)
3.4028235f38
julia> floatmax()
1.7976931348623157e308
julia> typemax(Float64)
Inf
Base.maxintfloat
— Functionmaxintfloat(T=Float64)
El número de punto flotante con valor entero consecutivo más grande que está representado exactamente en el tipo de punto flotante dado T
(que por defecto es Float64
).
Es decir, maxintfloat
devuelve el número de punto flotante con valor entero positivo más pequeño n
tal que n+1
no es representable exactamente en el tipo T
.
Cuando se necesita un valor de tipo Integer
, usa Integer(maxintfloat(T))
.
maxintfloat(T, S)
El mayor entero consecutivo representable en el tipo de punto flotante dado T
que tampoco excede el máximo entero representable por el tipo entero S
. De manera equivalente, es el mínimo de maxintfloat(T)
y typemax(S)
.
Base.eps
— Methodeps(::Type{T}) donde T<:AbstractFloat
eps()
Devuelve el epsilon de máquina del tipo de punto flotante T
(T = Float64
por defecto). Esto se define como la brecha entre 1 y el siguiente valor más grande representable por typeof(one(T))
, y es equivalente a eps(one(T))
. (Dado que eps(T)
es un límite en el error relativo de T
, es una cantidad "sin dimensiones" como one
.)
Ejemplos
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)
Devuelve la unidad en la última posición (ulp) de x
. Esta es la distancia entre los valores de punto flotante representables consecutivos en x
. En la mayoría de los casos, si la distancia a cada lado de x
es diferente, se toma el mayor de los dos, es decir,
eps(x) == max(x-prevfloat(x), nextfloat(x)-x)
Las excepciones a esta regla son los valores finitos más pequeños y más grandes (por ejemplo, nextfloat(-Inf)
y prevfloat(Inf)
para Float64
), que redondean al menor de los valores.
La razón de este comportamiento es que eps
limita el error de redondeo de punto flotante. Bajo el modo de redondeo predeterminado RoundNearest
, si $y$ es un número real y $x$ es el número de punto flotante más cercano a $y$, entonces
\[|y-x| \leq \operatorname{eps}(x)/2.\]
Véase también: nextfloat
, issubnormal
, floatmax
.
Ejemplos
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) # mayor Float64 finito
1.7976931348623157e308
julia> x + eps(x)/2 # redondea hacia arriba
Inf
julia> x + prevfloat(eps(x)/2) # redondea hacia abajo
1.7976931348623157e308
Base.instances
— Functioninstances(T::Type)
Devuelve una colección de todas las instancias del tipo dado, si es aplicable. Principalmente utilizado para tipos enumerados (ver @enum
).
Ejemplos
julia> @enum Color red blue green
julia> instances(Color)
(red, blue, green)
Special Types
Core.Any
— TypeAny::DataType
Any
es la unión de todos los tipos. Tiene la propiedad definitoria isa(x, Any) == true
para cualquier x
. Por lo tanto, Any
describe todo el universo de valores posibles. Por ejemplo, Integer
es un subconjunto de Any
que incluye Int
, Int8
y otros tipos de enteros.
Core.Union
— TypeUnion{Tipos...}
Un tipo Union
es un tipo abstracto que incluye todas las instancias de cualquiera de sus tipos de argumento. Esto significa que T <: Union{T,S}
y S <: Union{T,S}
.
Al igual que otros tipos abstractos, no se puede instanciar, incluso si todos sus argumentos no son abstractos.
Ejemplos
julia> IntOrString = Union{Int,AbstractString}
Union{Int64, AbstractString}
julia> 1 isa IntOrString # instancia de Int está incluida en la unión
true
julia> "¡Hola!" isa IntOrString # String también está incluido
true
julia> 1.0 isa IntOrString # Float64 no está incluido porque no es ni Int ni AbstractString
false
Ayuda Extendida
A diferencia de la mayoría de los otros tipos paramétricos, las uniones son covariantes en sus parámetros. Por ejemplo, Union{Real, String}
es un subtipo de Union{Number, AbstractString}
.
La unión vacía Union{}
es el tipo inferior de Julia.
Union{}
— KeywordUnion{}
Union{}
, el vacío Union
de tipos, es el tipo que no tiene valores. Es decir, tiene la propiedad definitoria isa(x, Union{}) == false
para cualquier x
. Base.Bottom
se define como su alias y el tipo de Union{}
es Core.TypeofBottom
.
Ejemplos
julia> isa(nothing, Union{})
false
Core.UnionAll
— TypeUnionAll
Una unión de tipos sobre todos los valores de un parámetro de tipo. UnionAll
se utiliza para describir tipos paramétricos donde los valores de algunos parámetros no son conocidos. Consulte la sección del manual sobre UnionAll Types.
Ejemplos
julia> typeof(Vector)
UnionAll
julia> typeof(Vector{Int})
DataType
Core.Tuple
— TypeTuple{Types...}
Una tupla es un contenedor de longitud fija que puede contener cualquier valor de diferentes tipos, pero no se puede modificar (es inmutable). Los valores se pueden acceder mediante indexación. Los literales de tupla se escriben con comas y paréntesis:
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}
Una tupla de longitud 1 debe escribirse con una coma, (1,)
, ya que (1)
sería solo un valor entre paréntesis. ()
representa la tupla vacía (de longitud 0).
Una tupla se puede construir a partir de un iterador utilizando un tipo Tuple
como constructor:
julia> Tuple(["a", 1])
("a", 1)
julia> Tuple{String, Float64}(["a", 1])
("a", 1.0)
Los tipos de tupla son covariantes en sus parámetros: Tuple{Int}
es un subtipo de Tuple{Any}
. Por lo tanto, Tuple{Any}
se considera un tipo abstracto, y los tipos de tupla son concretos solo si sus parámetros lo son. Las tuplas no tienen nombres de campo; los campos solo se acceden por índice. Los tipos de tupla pueden tener cualquier número de parámetros.
Consulta la sección del manual sobre Tipos de Tupla.
Consulta también Vararg
, NTuple
, ntuple
, tuple
, NamedTuple
.
Core.NTuple
— TypeNTuple{N, T}
Una forma compacta de representar el tipo para una tupla de longitud N
donde todos los elementos son del tipo T
.
Ejemplos
julia> isa((1, 2, 3, 4, 5, 6), NTuple{6, Int})
true
Ver también ntuple
.
Core.NamedTuple
— TypeNamedTuple
Los NamedTuple
s son, como su nombre sugiere, Tuple
s nombrados. Es decir, son una colección de valores similar a una tupla, donde cada entrada tiene un nombre único, representado como un Symbol
. Al igual que los Tuple
s, los NamedTuple
s son inmutables; ni los nombres ni los valores pueden ser modificados en su lugar después de la construcción.
Un tuple nombrado se puede crear como un literal de tupla con claves, por ejemplo, (a=1, b=2)
, o como un literal de tupla con un punto y coma después del paréntesis de apertura, por ejemplo, (; a=1, b=2)
(esta forma también acepta nombres generados programáticamente como se describe a continuación), o utilizando un tipo NamedTuple
como constructor, por ejemplo, NamedTuple{(:a, :b)}((1,2))
.
Acceder al valor asociado con un nombre en un tuple nombrado se puede hacer utilizando la sintaxis de acceso a campos, por ejemplo, x.a
, o utilizando getindex
, por ejemplo, x[:a]
o x[(:a, :b)]
. Un tuple de los nombres se puede obtener utilizando keys
, y un tuple de los valores se puede obtener utilizando values
.
La iteración sobre NamedTuple
s produce los valores sin los nombres. (Ver ejemplo a continuación.) Para iterar sobre los pares nombre-valor, utiliza la función pairs
.
El macro @NamedTuple
se puede usar para declarar convenientemente tipos NamedTuple
.
Ejemplos
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
De manera similar a cómo se pueden definir argumentos de palabra clave programáticamente, un tuple nombrado se puede crear dando pares name::Symbol => value
después de un punto y coma dentro de un literal de tupla. Esta sintaxis y la sintaxis name=value
se pueden mezclar:
julia> (; :a => 1, :b => 2, c=3)
(a = 1, b = 2, c = 3)
Los pares nombre-valor también se pueden proporcionar desglosando un tuple nombrado o cualquier iterador que produzca colecciones de dos valores que contengan cada uno un símbolo como primer valor:
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) # el último b sobrescribe el valor de nt1
(a = 1, b = 20, c = 3, d = 4)
julia> (; zip(keys, values)...) # zip produce tuplas como (:a, 1)
(a = 1, b = 2, c = 3)
Al igual que en los argumentos de palabra clave, los identificadores y las expresiones de punto implican nombres:
julia> x = 0
0
julia> t = (; x)
(x = 0,)
julia> (; t.x)
(x = 0,)
Los nombres implícitos de identificadores y expresiones de punto están disponibles a partir de Julia 1.5.
El uso de métodos getindex
con múltiples Symbol
s está disponible a partir de Julia 1.7.
Base.@NamedTuple
— Macro@NamedTuple{key1::Type1, key2::Type2, ...}
@NamedTuple begin key1::Type1; key2::Type2; ...; end
Este macro proporciona una sintaxis más conveniente para declarar tipos NamedTuple
. Devuelve un tipo NamedTuple
con las claves y tipos dados, equivalente a NamedTuple{(:key1, :key2, ...), Tuple{Type1,Type2,...}}
. Si se omite la declaración ::Type
, se toma como Any
. La forma begin ... end
permite que las declaraciones se dividan en múltiples líneas (similar a una declaración de struct
), pero es equivalente de otro modo. El macro NamedTuple
se utiliza al imprimir tipos NamedTuple
en, por ejemplo, el REPL.
Por ejemplo, la tupla (a=3.1, b="hello")
tiene un tipo NamedTuple{(:a, :b), Tuple{Float64, String}}
, que también se puede declarar a través de @NamedTuple
como:
julia> @NamedTuple{a::Float64, b::String}
@NamedTuple{a::Float64, b::String}
julia> @NamedTuple begin
a::Float64
b::String
end
@NamedTuple{a::Float64, b::String}
Este macro está disponible desde Julia 1.5.
Base.@Kwargs
— Macro@Kwargs{key1::Type1, key2::Type2, ...}
Este macro proporciona una forma conveniente de construir la representación de tipo de argumentos de palabra clave a partir de la misma sintaxis que @NamedTuple
. Por ejemplo, cuando tenemos una llamada a función como func([argumentos posicionales]; kw1=1.0, kw2="2")
, podemos usar este macro para construir la representación interna de tipo de los argumentos de palabra clave como @Kwargs{kw1::Float64, kw2::String}
. La sintaxis del macro está diseñada específicamente para simplificar el tipo de firma de un método de palabra clave cuando se imprime en la vista de traza de pila.
julia> @Kwargs{init::Int} # la representación interna de los argumentos de palabra clave
Base.Pairs{Symbol, Int64, Tuple{Symbol}, @NamedTuple{init::Int64}}
julia> sum("julia"; init=1)
ERROR: MethodError: no method matching +(::Char, ::Char)
La función `+` existe, pero no se define ningún método para esta combinación de tipos de argumento.
Los candidatos más cercanos son:
+(::Any, ::Any, ::Any, ::Any...)
@ Base operators.jl:585
+(::Integer, ::AbstractChar)
@ Base char.jl:247
+(::T, ::Integer) where T<:AbstractChar
@ Base char.jl:237
Stacktrace:
[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
Este macro está disponible a partir de Julia 1.10.
Base.Val
— TypeVal(c)
Devuelve Val{c}()
, que no contiene datos en tiempo de ejecución. Tipos como este se pueden usar para pasar la información entre funciones a través del valor c
, que debe ser un valor isbits
o un Symbol
. La intención de esta construcción es poder despachar sobre constantes directamente (en tiempo de compilación) sin tener que probar el valor de la constante en tiempo de ejecución.
Ejemplos
julia> f(::Val{true}) = "Good"
f (función genérica con 1 método)
julia> f(::Val{false}) = "Bad"
f (función genérica con 2 métodos)
julia> f(Val(true))
"Good"
Core.Vararg
— ConstantVararg{T,N}
El último parámetro de un tipo de tupla Tuple
puede ser el valor especial Vararg
, que denota cualquier número de elementos finales. Vararg{T,N}
corresponde exactamente a N
elementos del tipo T
. Finalmente, Vararg{T}
corresponde a cero o más elementos del tipo T
. Los tipos de tupla Vararg
se utilizan para representar los argumentos aceptados por los métodos de varargs (ver la sección sobre Funciones Varargs en el manual).
Véase también NTuple
.
Ejemplos
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)
Devuelve true
si x === nothing
, y devuelve false
si no.
Esta función requiere al menos Julia 1.1.
Véase también something
, Base.notnothing
, ismissing
.
Base.notnothing
— Functionnotnothing(x)
Lanza un error si x === nothing
, y devuelve x
si no.
Base.Some
— TypeSome{T}
Un tipo de envoltura utilizado en Union{Some{T}, Nothing}
para distinguir entre la ausencia de un valor (nothing
) y la presencia de un valor nothing
(es decir, Some(nothing)
).
Utiliza something
para acceder al valor envuelto por un objeto Some
.
Base.something
— Functionalgo(x...)
Devuelve el primer valor en los argumentos que no sea igual a nothing
, si lo hay. De lo contrario, lanza un error. Los argumentos de tipo Some
se desenvuelven.
Véase también coalesce
, skipmissing
, @something
.
Ejemplos
julia> algo(nothing, 1)
1
julia> algo(Some(1), nothing)
1
julia> algo(Some(nothing), 2) === nothing
true
julia> algo(missing, nothing)
missing
julia> algo(nothing, nothing)
ERROR: ArgumentError: No hay argumentos de valor presentes
Base.@something
— Macro@something(x...)
Versión de cortocircuito de something
.
Ejemplos
julia> f(x) = (println("f($x)"); nothing);
julia> a = 1;
julia> a = @something a f(2) f(3) error("No se puede encontrar un valor predeterminado para `a`")
1
julia> b = nothing;
julia> b = @something b f(2) f(3) error("No se puede encontrar un valor predeterminado para `b`")
f(2)
f(3)
ERROR: No se puede encontrar un valor predeterminado para `b`
[...]
julia> b = @something b f(2) f(3) Some(nothing)
f(2)
f(3)
julia> b === nothing
true
Este macro está disponible a partir de Julia 1.7.
Base.Enums.Enum
— TypeEnum{T<:Integer}
El supertipo abstracto de todos los tipos enumerados definidos con @enum
.
Base.Enums.@enum
— Macro@enum EnumName[::BaseType] value1[=x] value2[=y]
Crea un subtipo Enum{BaseType}
con el nombre EnumName
y valores de miembros de enumeración value1
y value2
con valores asignados opcionales de x
y y
, respectivamente. EnumName
se puede usar como otros tipos y los valores de los miembros de enumeración como valores regulares, como
Ejemplos
julia> @enum Fruit apple=1 orange=2 kiwi=3
julia> f(x::Fruit) = "Soy una fruta con valor: $(Int(x))"
f (función genérica con 1 método)
julia> f(apple)
"Soy una fruta con valor: 1"
julia> Fruit(1)
apple::Fruit = 1
Los valores también se pueden especificar dentro de un bloque begin
, por ejemplo:
@enum EnumName begin
value1
value2
end
BaseType
, que por defecto es Int32
, debe ser un subtipo primitivo de Integer
. Los valores de los miembros se pueden convertir entre el tipo de enumeración y BaseType
. read
y write
realizan estas conversiones automáticamente. En caso de que la enumeración se cree con un BaseType
no predeterminado, Integer(value1)
devolverá el entero value1
con el tipo BaseType
.
Para listar todas las instancias de una enumeración, usa instances
, por ejemplo:
julia> instances(Fruit)
(apple, orange, kiwi)
Es posible construir un símbolo a partir de una instancia de enumeración:
julia> Symbol(apple)
:apple
Core.Expr
— TypeExpr(head::Symbol, args...)
Un tipo que representa expresiones compuestas en código julia analizado (ASTs). Cada expresión consiste en un head
Symbol
que identifica qué tipo de expresión es (por ejemplo, una llamada, un bucle for, una declaración condicional, etc.), y subexpresiones (por ejemplo, los argumentos de una llamada). Las subexpresiones se almacenan en un campo Vector{Any}
llamado args
.
Consulta el capítulo del manual sobre Metaprogramación y la documentación para desarrolladores Julia ASTs.
Ejemplos
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
— TypeSímbolo
El tipo de objeto utilizado para representar identificadores en el código julia analizado (ASTs). También se utiliza a menudo como un nombre o etiqueta para identificar una entidad (por ejemplo, como una clave de diccionario). Los Símbolos
se pueden ingresar utilizando el operador de cita :
:
julia> :name
:name
julia> typeof(:name)
Símbolo
julia> x = 42
42
julia> eval(:x)
42
Los Símbolos
también se pueden construir a partir de cadenas u otros valores llamando al constructor Symbol(x...)
.
Los Símbolos
son inmutables y su implementación reutiliza el mismo objeto para todos los Símbolos
con el mismo nombre.
A diferencia de las cadenas, los Símbolos
son entidades "atómicas" o "escalares" que no admiten iteración sobre caracteres.
Core.Symbol
— MethodSymbol(x...) -> Symbol
Crea un Symbol
concatenando las representaciones en cadena de los argumentos.
Ejemplos
julia> Symbol("my", "name")
:myname
julia> Symbol("day", 4)
:day4
Core.Module
— TypeMódulo
Un Módulo
es un espacio de trabajo de variables globales separado. Consulta module
y la sección del manual sobre módulos para más detalles.
Module(name::Symbol=:anonymous, std_imports=true, default_names=true)
Devuelve un módulo con el nombre especificado. Un baremodule
corresponde a Module(:ModuleName, false)
Se puede crear un módulo vacío que no contenga nombres en absoluto con Module(:ModuleName, false, false)
. Este módulo no importará Base
ni Core
y no contiene una referencia a sí mismo.
Generic Functions
Core.Function
— TypeFunción
Tipo abstracto de todas las funciones.
Ejemplos
julia> isa(+, Function)
true
julia> typeof(sin)
typeof(sin) (tipo singleton de la función sin, subtipo de Function)
julia> ans <: Function
true
Base.hasmethod
— Functionhasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool
Determina si la función genérica dada tiene un método que coincide con el Tuple
de tipos de argumento dados con el límite superior de la edad del mundo dado por world
.
Si se proporciona un tuple de nombres de argumentos clave kwnames
, esto también verifica si el método de f
que coincide con t
tiene los nombres de argumentos clave dados. Si el método coincidente acepta un número variable de argumentos clave, por ejemplo, con kwargs...
, cualquier nombre dado en kwnames
se considera válido. De lo contrario, los nombres proporcionados deben ser un subconjunto de los argumentos clave del método.
Véase también applicable
.
Proporcionar nombres de argumentos clave requiere Julia 1.2 o posterior.
Ejemplos
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 acepta kwargs arbitrarios
true
Core.applicable
— Functionapplicable(f, args...) -> Bool
Determina si la función genérica dada tiene un método aplicable a los argumentos dados.
Ver también hasmethod
.
Ejemplos
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
Determina si dos métodos m1
y m2
pueden ser ambiguos para alguna firma de llamada. Esta prueba se realiza en el contexto de otros métodos de la misma función; de forma aislada, m1
y m2
podrían ser ambiguos, pero si se ha definido un tercer método que resuelve la ambigüedad, esto devuelve false
. Alternativamente, de forma aislada m1
y m2
podrían estar ordenados, pero si un tercer método no puede ser ordenado con ellos, pueden causar una ambigüedad juntos.
Para tipos paramétricos, el argumento clave ambiguous_bottom
controla si Union{}
cuenta como una intersección ambigua de parámetros de tipo: cuando es true
, se considera ambigua; cuando es false
, no lo es.
Ejemplos
julia> foo(x::Complex{<:Integer}) = 1
foo (función genérica con 1 método)
julia> foo(x::Complex{<:Rational}) = 2
foo (función genérica con 2 métodos)
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...)
Invoca un método para la función genérica dada f
que coincide con los tipos especificados argtypes
en los argumentos especificados args
y pasando los argumentos de palabra clave kwargs
. Los argumentos args
deben conformarse con los tipos especificados en argtypes
, es decir, la conversión no se realiza automáticamente. Este método permite invocar un método que no sea el método más específico que coincide, lo cual es útil cuando se necesita explícitamente el comportamiento de una definición más general (a menudo como parte de la implementación de un método más específico de la misma función).
Ten cuidado al usar invoke
para funciones que no escribes. Qué definición se utiliza para los argtypes
dados es un detalle de implementación a menos que la función indique explícitamente que llamar con ciertos argtypes
es parte de la API pública. Por ejemplo, el cambio entre f1
y f2
en el ejemplo a continuación se considera generalmente compatible porque el cambio es invisible para el llamador con una llamada normal (no invoke
). Sin embargo, el cambio es visible si usas invoke
.
Ejemplos
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...)
Proporciona una forma conveniente de llamar a invoke
al expandir @invoke f(arg1::T1, arg2::T2; kwargs...)
a invoke(f, Tuple{T1,T2}, arg1, arg2; kwargs...)
. Cuando se omite la anotación de tipo de un argumento, se reemplaza por Core.Typeof
de ese argumento. Para invocar un método donde un argumento no tiene tipo o está explícitamente tipado como Any
, anota el argumento con ::Any
.
También admite la siguiente sintaxis:
@invoke (x::X).f
se expande ainvoke(getproperty, Tuple{X,Symbol}, x, :f)
@invoke (x::X).f = v::V
se expande ainvoke(setproperty!, Tuple{X,Symbol,V}, x, :f, v)
@invoke (xs::Xs)[i::I]
se expande ainvoke(getindex, Tuple{Xs,I}, xs, i)
@invoke (xs::Xs)[i::I] = v::V
se expande ainvoke(setindex!, Tuple{Xs,V,I}, xs, v, i)
Ejemplos
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))
Esta macro requiere Julia 1.7 o posterior.
Esta macro se exporta a partir de Julia 1.9.
La sintaxis adicional es compatible a partir de Julia 1.10.
Base.invokelatest
— Functioninvokelatest(f, args...; kwargs...)
Llama a f(args...; kwargs...)
, pero garantiza que se ejecutará el método más reciente de f
. Esto es útil en circunstancias especializadas, por ejemplo, bucles de eventos de larga duración o funciones de devolución de llamada que pueden llamar a versiones obsoletas de una función f
. (La desventaja es que invokelatest
es algo más lento que llamar a f
directamente, y el tipo del resultado no puede ser inferido por el compilador.)
Antes de Julia 1.9, esta función no se exportaba y se llamaba como Base.invokelatest
.
Base.@invokelatest
— Macro@invokelatest f(args...; kwargs...)
Proporciona una forma conveniente de llamar a invokelatest
. @invokelatest f(args...; kwargs...)
simplemente se expandirá en Base.invokelatest(f, args...; kwargs...)
.
También admite la siguiente sintaxis:
@invokelatest x.f
se expande aBase.invokelatest(getproperty, x, :f)
@invokelatest x.f = v
se expande aBase.invokelatest(setproperty!, x, :f, v)
@invokelatest xs[i]
se expande aBase.invokelatest(getindex, xs, i)
@invokelatest xs[i] = v
se expande aBase.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))
Esta macro requiere Julia 1.7 o posterior.
Antes de Julia 1.9, esta macro no se exportaba y se llamaba como Base.@invokelatest
.
La sintaxis adicional x.f
y xs[i]
requiere Julia 1.10.
new
— Keywordnew, or new{A,B,...}
Función especial disponible para constructores internos que crea un nuevo objeto del tipo. La forma new{A,B,...} especifica explícitamente los valores de los parámetros para tipos paramétricos. Consulte la sección del manual sobre Inner Constructor Methods para más información.
Base.:|>
— Function|>(x, f)
Operador infijo que aplica la función f
al argumento x
. Esto permite que f(g(x))
se escriba como x |> g |> f
. Cuando se usa con funciones anónimas, generalmente se requieren paréntesis alrededor de la definición para obtener la cadena deseada.
Ejemplos
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
Componer funciones: es decir, (f ∘ g)(args...; kwargs...)
significa f(g(args...; kwargs...))
. El símbolo ∘
se puede ingresar en el REPL de Julia (y en la mayoría de los editores, configurados adecuadamente) escribiendo \circ<tab>
.
La composición de funciones también funciona en forma de prefijo: ∘(f, g)
es lo mismo que f ∘ g
. La forma de prefijo admite la composición de múltiples funciones: ∘(f, g, h) = f ∘ g ∘ h
y el splatting ∘(fs...)
para componer una colección iterable de funciones. El último argumento de ∘
se ejecuta primero.
La composición de múltiples funciones requiere al menos Julia 1.4.
La composición de una función ∘(f) requiere al menos Julia 1.5.
El uso de argumentos de palabra clave requiere al menos Julia 1.7.
Ejemplos
julia> map(uppercase∘first, ["apple", "banana", "carrot"])
3-element Vector{Char}:
'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)
'C': ASCII/Unicode U+0043 (category Lu: Letter, uppercase)
julia> (==(6)∘length).(["apple", "banana", "carrot"])
3-element BitVector:
0
1
1
julia> fs = [
x -> 2x
x -> x-1
x -> x/2
x -> x+1
];
julia> ∘(fs...)(3)
2.0
Ver también ComposedFunction
, !f::Function
.
Base.ComposedFunction
— TypeComposedFunction{Outer,Inner} <: Function
Representa la composición de dos objetos llamables outer::Outer
y inner::Inner
. Es decir
ComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))
La forma preferida de construir una instancia de ComposedFunction
es usar el operador de composición ∘
:
julia> sin ∘ cos === ComposedFunction(sin, cos)
true
julia> typeof(sin∘cos)
ComposedFunction{typeof(sin), typeof(cos)}
Las piezas compuestas se almacenan en los campos de ComposedFunction
y se pueden recuperar de la siguiente manera:
julia> composition = sin ∘ cos
sin ∘ cos
julia> composition.outer === sin
true
julia> composition.inner === cos
true
ComposedFunction requiere al menos Julia 1.6. En versiones anteriores ∘
devuelve una función anónima en su lugar.
Ver también ∘
.
Base.splat
— Functionsplat(f)
Equivalente a
my_splat(f) = args->f(args...)
es decir, dado una función, devuelve una nueva función que toma un argumento y lo expande en la función original. Esto es útil como un adaptador para pasar una función de múltiples argumentos en un contexto que espera un solo argumento, pero pasa una tupla como ese único argumento.
Ejemplos
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)
Un tipo que representa una versión parcialmente aplicada de la función de dos argumentos f
, con el primer argumento fijado al valor "x". En otras palabras, Fix1(f, x)
se comporta de manera similar a y->f(x, y)
.
Véase también Fix2
.
Base.Fix2
— TypeFix2(f, x)
Un tipo que representa una versión parcialmente aplicada de la función de dos argumentos f
, con el segundo argumento fijado al valor "x". En otras palabras, Fix2(f, x)
se comporta de manera similar a y->f(y, x)
.
Syntax
Core.eval
— FunctionCore.eval(m::Module, expr)
Evalúa una expresión en el módulo dado y devuelve el resultado.
eval
— Functioneval(expr)
Evalúa una expresión en el ámbito global del módulo que la contiene. Cada Module
(excepto aquellos definidos con baremodule
) tiene su propia definición de eval
con un argumento, que evalúa expresiones en ese módulo.
Base.@eval
— Macro@eval [mod,] ex
Evalúa una expresión con valores interpolados en ella usando eval
. Si se proporcionan dos argumentos, el primero es el módulo en el que se evalúa.
Base.evalfile
— Functionevalfile(path::AbstractString, args::Vector{String}=String[])
Carga el archivo en un módulo anónimo usando include
, evalúa todas las expresiones y devuelve el valor de la última expresión. El argumento opcional args
se puede usar para establecer los argumentos de entrada del script (es decir, la variable global ARGS
). Ten en cuenta que las definiciones (por ejemplo, métodos, globales) se evalúan en el módulo anónimo y no afectan al módulo actual.
Ejemplos
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)
Solo válido en el contexto de un Expr
devuelto por un macro. Previene que el paso de higiene del macro convierta las variables incrustadas en variables gensym. Consulta la sección de Macros del capítulo de Metaprogramación del manual para más detalles y ejemplos.
Base.@inbounds
— Macro@inbounds(blk)
Elimina la verificación de límites de matriz dentro de las expresiones.
En el ejemplo a continuación, se omite la verificación de rango para referenciar el elemento i
de la matriz A
para mejorar el rendimiento.
function sum(A::AbstractArray)
r = zero(eltype(A))
for i in eachindex(A)
@inbounds r += A[i]
end
return r
end
Usar @inbounds
puede devolver resultados incorrectos/caídas/corrupción para índices fuera de límites. El usuario es responsable de verificarlo manualmente. Solo use @inbounds
cuando esté seguro, según la información disponible localmente, de que todos los accesos están dentro de los límites. En particular, usar 1:length(A)
en lugar de eachindex(A)
en una función como la anterior no está seguro dentro de los límites porque el primer índice de A
puede no ser 1
para todos los tipos definidos por el usuario que son subtipos de AbstractArray
.
Base.@boundscheck
— Macro@boundscheck(blk)
Anota la expresión blk
como un bloque de verificación de límites, permitiendo que sea elidido por @inbounds
.
La función en la que se escribe @boundscheck
debe ser inlined en su llamador para que @inbounds
tenga efecto.
Ejemplos
julia> @inline function g(A, i)
@boundscheck checkbounds(A, i)
return "accediendo ($A)[$i]"
end;
julia> f1() = return g(1:2, -1);
julia> f2() = @inbounds return g(1:2, -1);
julia> f1()
ERROR: BoundsError: intento de acceder a UnitRange{Int64} de 2 elementos en el índice [-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()
"accediendo (1:2)[-1]"
La anotación @boundscheck
te permite, como escritor de bibliotecas, optar por permitir que otro código elimine tus verificaciones de límites con @inbounds
. Como se mencionó allí, el llamador debe verificar—usando información a la que pueden acceder—que sus accesos son válidos antes de usar @inbounds
. Por ejemplo, para indexar en tus subclases de AbstractArray
, esto implica verificar los índices contra sus axes
. Por lo tanto, las anotaciones @boundscheck
solo deben añadirse a una implementación de getindex
o setindex!
después de que estés seguro de que su comportamiento es correcto.
Base.@propagate_inbounds
— Macro@propagate_inbounds
Indica al compilador que inserte una función en línea mientras retiene el contexto de inbounds del llamador.
Base.@inline
— Macro@inline
Dale una pista al compilador de que esta función merece ser inlined.
Las funciones pequeñas típicamente no necesitan la anotación @inline
, ya que el compilador lo hace automáticamente. Al usar @inline
en funciones más grandes, se puede dar un empujón adicional al compilador para que las inlined.
@inline
se puede aplicar inmediatamente antes de una definición de función o dentro de un cuerpo de función.
# anotar definición de forma larga
@inline function longdef(x)
...
end
# anotar definición de forma corta
@inline shortdef(x) = ...
# anotar función anónima que crea un bloque `do`
f() do
@inline
...
end
El uso dentro de un cuerpo de función requiere al menos Julia 1.8.
@inline block
Dale una pista al compilador de que las llamadas dentro de block
merecen ser inlined.
# El compilador intentará inlined `f`
@inline f(...)
# El compilador intentará inlined `f`, `g` y `+`
@inline f(...) + g(...)
Una anotación de sitio de llamada siempre tiene precedencia sobre la anotación aplicada a la definición de la función llamada:
@noinline function explicit_noinline(args...)
# cuerpo
end
let
@inline explicit_noinline(args...) # será inlined
end
Cuando hay anotaciones de sitio de llamada anidadas, la anotación más interna tiene precedencia:
@noinline let a0, b0 = ...
a = @inline f(a0) # el compilador intentará inlined esta llamada
b = f(b0) # el compilador NO intentará inlined esta llamada
return a, b
end
Aunque una anotación de sitio de llamada intentará forzar el inlining independientemente del modelo de costos, aún hay posibilidades de que no pueda tener éxito. Especialmente, las llamadas recursivas no pueden ser inlined incluso si están anotadas como @inline
d.
La anotación de sitio de llamada requiere al menos Julia 1.8.
Base.@noinline
— Macro@noinline
Dale una pista al compilador de que no debe inlining una función.
Las funciones pequeñas se inlinan automáticamente. Al usar @noinline
en funciones pequeñas, se puede prevenir el auto-inlining.
@noinline
se puede aplicar inmediatamente antes de una definición de función o dentro de un cuerpo de función.
# anotar definición de forma larga
@noinline function longdef(x)
...
end
# anotar definición de forma corta
@noinline shortdef(x) = ...
# anotar función anónima que crea un bloque `do`
f() do
@noinline
...
end
El uso dentro de un cuerpo de función requiere al menos Julia 1.8.
@noinline block
Dale una pista al compilador de que no debe inlining las llamadas dentro de block
.
# El compilador intentará no inlining `f`
@noinline f(...)
# El compilador intentará no inlining `f`, `g` y `+`
@noinline f(...) + g(...)
Una anotación de sitio de llamada siempre tiene precedencia sobre la anotación aplicada a la definición de la función llamada:
@inline function explicit_inline(args...)
# cuerpo
end
let
@noinline explicit_inline(args...) # no será inlined
end
Cuando hay anotaciones de sitio de llamada anidadas, la anotación más interna tiene precedencia:
@inline let a0, b0 = ...
a = @noinline f(a0) # el compilador NO intentará inlining esta llamada
b = f(b0) # el compilador intentará inlining esta llamada
return a, b
end
La anotación de sitio de llamada requiere al menos Julia 1.8.
Si la función es trivial (por ejemplo, devuelve una constante) podría ser inlined de todos modos.
Base.@nospecialize
— Macro@nospecialize
Aplicado a un nombre de argumento de función, indica al compilador que la implementación del método no debe especializarse para diferentes tipos de ese argumento, sino que debe utilizar el tipo declarado para ese argumento. Se puede aplicar a un argumento dentro de una lista de argumentos formal, o en el cuerpo de la función. Cuando se aplica a un argumento, el macro debe envolver toda la expresión del argumento, por ejemplo, @nospecialize(x::Real)
o @nospecialize(i::Integer...)
en lugar de envolver solo el nombre del argumento. Cuando se usa en el cuerpo de una función, el macro debe ocurrir en posición de declaración y antes de cualquier código.
Cuando se usa sin argumentos, se aplica a todos los argumentos del ámbito padre. En el ámbito local, esto significa todos los argumentos de la función que contiene. En el ámbito global (de nivel superior), esto significa todos los métodos definidos posteriormente en el módulo actual.
La especialización se puede restablecer a la predeterminada utilizando @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
afecta la generación de código pero no la inferencia: limita la diversidad del código nativo resultante, pero no impone ninguna limitación (más allá de las estándar) sobre la inferencia de tipos. Usa Base.@nospecializeinfer
junto con @nospecialize
para suprimir adicionalmente la inferencia.
Ejemplos
julia> f(A::AbstractArray) = g(A)
f (función genérica con 1 método)
julia> @noinline g(@nospecialize(A::AbstractArray)) = A[1]
g (función genérica con 1 método)
julia> @code_typed f([1.0])
CodeInfo(
1 ─ %1 = invoke Main.g(_2::AbstractArray)::Float64
└── return %1
) => Float64
Aquí, la anotación @nospecialize
resulta en el equivalente de
f(A::AbstractArray) = invoke(g, Tuple{AbstractArray}, A)
asegurando que solo se generará una versión del código nativo para g
, una que sea genérica para cualquier AbstractArray
. Sin embargo, el tipo de retorno específico aún se infiere para ambos, g
y f
, y esto todavía se utiliza para optimizar los llamadores de f
y g
.
Base.@specialize
— Macro@specialize
Restablece la sugerencia de especialización para un argumento a la predeterminada. Para más detalles, consulta @nospecialize
.
Base.@nospecializeinfer
— MacroBase.@nospecializeinfer function f(args...)
@nospecialize ...
...
end
Base.@nospecializeinfer f(@nospecialize args...) = ...
Indica al compilador que infiera f
utilizando los tipos declarados de los argumentos @nospecialize
d. Esto se puede usar para limitar el número de especializaciones generadas por el compilador durante la inferencia.
Ejemplos
julia> f(A::AbstractArray) = g(A)
f (función genérica con 1 método)
julia> @noinline Base.@nospecializeinfer g(@nospecialize(A::AbstractArray)) = A[1]
g (función genérica con 1 método)
julia> @code_typed f([1.0])
CodeInfo(
1 ─ %1 = invoke Main.g(_2::AbstractArray)::Any
└── return %1
) => Any
En este ejemplo, f
será inferido para cada tipo específico de A
, pero g
solo será inferido una vez con el tipo de argumento declarado A::AbstractArray
, lo que significa que el compilador probablemente no verá el tiempo excesivo de inferencia en él mientras no puede inferir el tipo de retorno concreto. Sin el @nospecializeinfer
, f([1.0])
inferiría el tipo de retorno de g
como Float64
, indicando que la inferencia se ejecutó para g(::Vector{Float64})
a pesar de la prohibición de la generación de código especializado.
Usar Base.@nospecializeinfer
requiere la versión 1.10 de Julia.
```
Base.@constprop
— MacroBase.@constprop configuración [ex]
Controla el modo de propagación de constantes interprocedimental para la función anotada.
Se admiten dos configuraciones
:
Base.@constprop :agresivo [ex]
: aplica la propagación de constantes de manera agresiva. Para un método donde el tipo de retorno depende del valor de los argumentos, esto puede generar mejores resultados de inferencia a costa de un tiempo de compilación adicional.Base.@constprop :ninguno [ex]
: desactiva la propagación de constantes. Esto puede reducir los tiempos de compilación para funciones que Julia de otro modo podría considerar dignas de propagación de constantes. Los casos comunes son para funciones con argumentos de tipoBool
oSymbol
o argumentos de palabra clave.
Base.@constprop
se puede aplicar inmediatamente antes de una definición de función o dentro de un cuerpo de función.
# anotar definición en forma larga
Base.@constprop :agresivo function longdef(x)
...
end
# anotar definición en forma corta
Base.@constprop :agresivo shortdef(x) = ...
# anotar función anónima que crea un bloque `do`
f() do
Base.@constprop :agresivo
...
end
El uso dentro de un cuerpo de función requiere al menos Julia 1.10.
Base.gensym
— Functiongensym([tag])
Genera un símbolo que no entrará en conflicto con otros nombres de variables (en el mismo módulo).
Base.@gensym
— Macro@gensym
Genera un símbolo gensym para una variable. Por ejemplo, @gensym x y
se transforma en x = gensym("x"); y = gensym("y")
.
var"name"
— Keywordvar
La sintaxis var"#example#"
se refiere a una variable llamada Symbol("#example#")
, aunque #example#
no sea un nombre de identificador válido en Julia.
Esto puede ser útil para la interoperabilidad con lenguajes de programación que tienen diferentes reglas para la construcción de identificadores válidos. Por ejemplo, para referirse a la variable R
draw.segments
, puedes usar var"draw.segments"
en tu código Julia.
También se utiliza para show
el código fuente de Julia que ha pasado por la higiene de macros o que de otro modo contiene nombres de variables que no se pueden analizar normalmente.
Ten en cuenta que esta sintaxis requiere soporte del analizador, por lo que se expande directamente por el analizador en lugar de implementarse como una macro de cadena normal @var_str
.
Esta sintaxis requiere al menos Julia 1.3.
Base.@goto
— Macro@goto name
@goto name
salta incondicionalmente a la declaración en la ubicación @label name
.
@label
y @goto
no pueden crear saltos a diferentes declaraciones de nivel superior. Los intentos causan un error. Para seguir usando @goto
, encierra @label
y @goto
en un bloque.
Base.@label
— Macro@label name
Etiqueta una declaración con la etiqueta simbólica name
. La etiqueta marca el punto final de un salto incondicional con @goto name
.
Base.SimdLoop.@simd
— Macro@simd
Anotar un bucle for
para permitir que el compilador tome libertades adicionales para permitir el reordenamiento del bucle.
Esta característica es experimental y podría cambiar o desaparecer en futuras versiones de Julia. El uso incorrecto de la macro @simd
puede causar resultados inesperados.
El objeto iterado en un bucle @simd for
debe ser un rango unidimensional. Al usar @simd
, estás afirmando varias propiedades del bucle:
- Es seguro ejecutar iteraciones en un orden arbitrario o superpuesto, con especial consideración para las variables de reducción.
- Las operaciones de punto flotante sobre las variables de reducción pueden ser reordenadas o contraídas, lo que puede causar resultados diferentes que sin
@simd
.
En muchos casos, Julia puede vectorizar automáticamente los bucles internos sin el uso de @simd
. Usar @simd
le da al compilador un poco más de margen para hacerlo posible en más situaciones. En cualquier caso, tu bucle interno debe tener las siguientes propiedades para permitir la vectorización:
- El bucle debe ser un bucle más interno.
- El cuerpo del bucle debe ser código de línea recta. Por lo tanto,
@inbounds
es actualmente necesario para todos los accesos a arreglos. El compilador a veces puede convertir expresiones cortas&&
,||
y?:
en código de línea recta si es seguro evaluar todos los operandos incondicionalmente. Considera usar la funciónifelse
en lugar de?:
en el bucle si es seguro hacerlo. - Los accesos deben tener un patrón de paso y no pueden ser "gathers" (lecturas de índices aleatorios) o "scatters" (escrituras de índices aleatorios).
- El paso debe ser un paso unitario.
El @simd
no afirma por defecto que el bucle esté completamente libre de dependencias de memoria llevadas por el bucle, lo cual es una suposición que puede ser fácilmente violada en código genérico. Si estás escribiendo código no genérico, puedes usar @simd ivdep for ... end
para también afirmar que:
- No existen dependencias de memoria llevadas por el bucle.
- Ninguna iteración espera nunca a que una iteración anterior avance.
Base.@polly
— Macro@polly
Indica al compilador que aplique el optimizador poligonal Polly a una función.
Base.@generated
— Macro@generated f
@generated
se utiliza para anotar una función que será generada. En el cuerpo de la función generada, solo se pueden leer los tipos de los argumentos (no los valores). La función devuelve una expresión citada que se evalúa cuando se llama a la función. El macro @generated
no debe usarse en funciones que mutan el ámbito global o dependen de elementos mutables.
Consulta Metaprogramming para más detalles.
Ejemplos
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 configurando... [ex]
Sobrescribe el modelado de efectos del compilador. Este macro se puede usar en varios contextos:
- Inmediatamente antes de una definición de método, para sobrescribir todo el modelado de efectos del método aplicado.
- Dentro de un cuerpo de función sin argumentos, para sobrescribir todo el modelado de efectos del método que lo contiene.
- Aplicado a un bloque de código, para sobrescribir el modelado de efectos local del bloque de código aplicado.
Ejemplos
julia> Base.@assume_effects :terminates_locally function fact(x)
# uso 1:
# este :terminates_locally permite que `fact` sea evaluado como constante
res = 1
0 ≤ x < 20 || error("mal fact")
while x > 1
res *= x
x -= 1
end
return res
end
fact (función genérica con 1 método)
julia> code_typed() do
fact(12)
end |> only
CodeInfo(
1 ─ return 479001600
) => Int64
julia> code_typed() do
map((2,3,4)) do x
# uso 2:
# este :terminates_locally permite que esta función anónima sea evaluada como constante
Base.@assume_effects :terminates_locally
res = 1
0 ≤ x < 20 || error("mal fact")
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("mal fact")
# uso 3:
# con esta anotación :terminates_locally el compilador omite la contaminación
# del efecto `:terminates` dentro de este bloque `while`, permitiendo que la función
# anónima padre sea evaluada como constante
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}
Usar Base.@assume_effects
requiere la versión 1.8 de Julia.
El uso dentro de un cuerpo de función requiere al menos Julia 1.10.
La anotación de bloque de código requiere al menos Julia 1.11.
El uso inapropiado de este macro causa comportamiento indefinido (incluyendo bloqueos, respuestas incorrectas u otros errores difíciles de rastrear). Úselo con cuidado y solo como último recurso si es absolutamente necesario. Incluso en tal caso, DEBE tomar todas las medidas posibles para minimizar la fuerza de la afirmación de efecto (por ejemplo, no use :total
si :nothrow
hubiera sido suficiente).
En general, cada valor de setting
hace una afirmación sobre el comportamiento de la función, sin requerir que el compilador demuestre que este comportamiento es realmente cierto. Estas afirmaciones se hacen para todas las edades del mundo. Por lo tanto, es aconsejable limitar el uso de funciones genéricas que pueden extenderse más tarde para invalidar la suposición (lo que causaría un comportamiento indefinido).
Los siguientes setting
s son compatibles.
:consistent
:effect_free
:nothrow
:terminates_globally
:terminates_locally
:notaskstate
:inaccessiblememonly
:noub
:noub_if_noinbounds
:nortcall
:foldable
:removable
:total
Ayuda extendida
:consistent
La configuración :consistent
afirma que para entradas iguales (===
):
- La forma de terminación (valor de retorno, excepción, no terminación) siempre será la misma.
- Si el método retorna, los resultados siempre serán iguales.
Esto implica en particular que el método no debe devolver un objeto mutable recién asignado. Múltiples asignaciones de objetos mutables (incluso con contenidos idénticos) no son iguales.
La afirmación :consistent
se hace por edad del mundo. Más formalmente, escriba $fᵢ$ para la evaluación de $f$ en la edad del mundo $i$, entonces esta configuración requiere:
\[∀ i, x, y: x ≡ y → fᵢ(x) ≡ fᵢ(y)\]
Sin embargo, para dos edades del mundo $i$, $j$ tales que $i ≠ j$, podemos tener $fᵢ(x) ≢ fⱼ(y)$.
Una implicación adicional es que las funciones :consistent
no pueden hacer que su valor de retorno dependa del estado del heap o de cualquier otro estado global que no sea constante para una edad del mundo dada.
La :consistent
incluye todas las reescrituras legales realizadas por el optimizador. Por ejemplo, las operaciones de fastmath de punto flotante no se consideran :consistent
, porque el optimizador puede reescribirlas causando que la salida no sea :consistent
, incluso para la misma edad del mundo (por ejemplo, porque una se ejecutó en el intérprete, mientras que la otra fue optimizada).
Si las funciones :consistent
terminan lanzando una excepción, esa excepción en sí misma no está obligada a cumplir con el requisito de igualdad especificado anteriormente.
:effect_free
La configuración :effect_free
afirma que el método está libre de efectos secundarios semánticamente visibles externamente. La siguiente es una lista incompleta de efectos secundarios semánticamente visibles externamente:
- Cambiar el valor de una variable global.
- Mutar el heap (por ejemplo, un arreglo o valor mutable), excepto como se indica a continuación.
- Cambiar la tabla de métodos (por ejemplo, a través de llamadas a eval).
- Entrada/salida de archivos/red/etc.
- Cambio de tareas.
Sin embargo, lo siguiente no es semánticamente visible, incluso si puede ser observable:
- Asignaciones de memoria (tanto mutables como inmutables).
- Tiempo transcurrido.
- Recolección de basura.
- Mutaciones del heap de objetos cuya vida útil no excede el método (es decir, que fueron asignados en el método y no escapan).
- El valor devuelto (que es externamente visible, pero no un efecto secundario).
La regla general aquí es que un efecto secundario visible externamente es cualquier cosa que afectaría la ejecución del resto del programa si la función no se ejecutara.
La afirmación :effect_free
se hace tanto para el método en sí como para cualquier código que se ejecute por el método. Tenga en cuenta que la afirmación debe ser válida para todas las edades del mundo y limite el uso de esta afirmación en consecuencia.
:nothrow
La configuración :nothrow
afirma que este método no lanza una excepción (es decir, siempre devolverá un valor o nunca devolverá).
Es permisible que los métodos anotados con :nothrow
utilicen el manejo de excepciones internamente siempre que la excepción no se vuelva a lanzar fuera del método mismo.
Si la ejecución de un método puede generar MethodError
s y excepciones similares, entonces el método no se considera :nothrow
. Sin embargo, tenga en cuenta que errores dependientes del entorno como StackOverflowError
o InterruptException
no son modelados por este efecto y, por lo tanto, un método que puede resultar en StackOverflowError
no necesita ser !:nothrow
(aunque generalmente también debería ser !:terminates
).
:terminates_globally
La configuración :terminates_globally
afirma que este método eventualmente terminará (ya sea normalmente o anormalmente), es decir, no entra en un bucle indefinido.
Esta afirmación :terminates_globally
cubre cualquier otro método llamado por el método anotado.
El compilador considerará esto como una fuerte indicación de que el método terminará relativamente rápidamente y puede (si es legal de otro modo) llamar a este método en tiempo de compilación. Es decir, es una mala idea anotar esta configuración en un método que técnicamente, pero no prácticamente, termina.
:terminates_locally
La configuración :terminates_locally
es como :terminates_globally
, excepto que solo se aplica al flujo de control sintáctico dentro del método anotado. Por lo tanto, es una afirmación mucho más débil (y por lo tanto más segura) que permite la posibilidad de no terminación si el método llama a algún otro método que no termina.
:terminates_globally
implica :terminates_locally
.
:notaskstate
La configuración :notaskstate
afirma que el método no utiliza ni modifica el estado de tarea local (almacenamiento local de tarea, estado de RNG, etc.) y, por lo tanto, puede ser movido entre tareas sin resultados observables.
La implementación del manejo de excepciones utiliza el estado almacenado en el objeto de tarea. Sin embargo, este estado actualmente no se considera dentro del alcance de :notaskstate
y se rastrea por separado utilizando el efecto :nothrow
.
La afirmación :notaskstate
concierne al estado de la tarea actualmente en ejecución. Si se obtiene una referencia a un objeto Task
por algún otro medio que no considera qué tarea está actualmente en ejecución, el efecto :notaskstate
no necesita ser contaminado. Esto es cierto, incluso si dicho objeto de tarea resulta ser ===
a la tarea actualmente en ejecución.
El acceso al estado de tarea generalmente también resulta en la contaminación de otros efectos, como :effect_free
(si se modifica el estado de tarea) o :consistent
(si se utiliza el estado de tarea en el cálculo del resultado). En particular, el código que no es :notaskstate
, pero es :effect_free
y :consistent
puede ser eliminado como código muerto y, por lo tanto, promovido a :total
.
:inaccessiblememonly
La configuración :inaccessiblememonly
afirma que el método no accede ni modifica memoria mutable accesible externamente. Esto significa que el método puede acceder o modificar memoria mutable para objetos recién asignados que no son accesibles por otros métodos o ejecución de nivel superior antes de retornar del método, pero no puede acceder ni modificar ningún estado global mutable o memoria mutable apuntada por sus argumentos.
A continuación se presenta una lista incompleta de ejemplos que invalidan esta suposición:
- una referencia global o llamada
getglobal
para acceder a una variable global mutable - una asignación global o llamada
setglobal!
para realizar una asignación a una variable global no constante - llamada
setfield!
que cambia un campo de una variable mutable global
Esta afirmación :inaccessiblememonly
cubre cualquier otro método llamado por el método anotado.
:noub
La configuración :noub
afirma que el método no ejecutará ningún comportamiento indefinido (para cualquier entrada). Tenga en cuenta que el comportamiento indefinido puede técnicamente causar que el método viole cualquier otra afirmación de efecto (como :consistent
o :effect_free
) también, pero no modelamos esto, y asumen la ausencia de comportamiento indefinido.
:nortcall
La configuración :nortcall
afirma que el método no llama a Core.Compiler.return_type
, y que cualquier otro método que este método pueda llamar tampoco llama a Core.Compiler.return_type
.
Para ser precisos, esta afirmación se puede usar cuando no se realiza una llamada a Core.Compiler.return_type
en tiempo de ejecución; es decir, cuando el resultado de Core.Compiler.return_type
se conoce exactamente en tiempo de compilación y la llamada es eliminada por el optimizador. Sin embargo, dado que si el resultado de Core.Compiler.return_type
se pliega en tiempo de compilación depende en gran medida de la implementación del compilador, generalmente es arriesgado afirmar esto si el método en cuestión utiliza Core.Compiler.return_type
de alguna forma.
:foldable
Esta configuración es un atajo conveniente para el conjunto de efectos que el compilador requiere que se garanticen para evaluar una llamada como constante en tiempo de compilación. Actualmente es equivalente a los siguientes setting
s:
:consistent
:effect_free
:terminates_globally
:noub
:nortcall
Esta lista en particular no incluye :nothrow
. El compilador aún intentará la propagación constante y notará cualquier error lanzado en tiempo de compilación. Tenga en cuenta, sin embargo, que por los requisitos de :consistent
, cualquier llamada anotada de este tipo debe lanzar consistentemente dado los mismos valores de argumento.
Una anotación explícita @inbounds
dentro de la función también deshabilitará la evaluación constante y no será anulada por :foldable
.
:removable
Esta configuración es un atajo conveniente para el conjunto de efectos que el compilador requiere que se garanticen para eliminar una llamada cuyo resultado no se utiliza en tiempo de compilación. Actualmente es equivalente a los siguientes setting
s:
:effect_free
:nothrow
:terminates_globally
:total
Esta configuración es el conjunto máximo posible de efectos. Actualmente implica los siguientes otros setting
s:
:consistent
:effect_free
:nothrow
:terminates_globally
:notaskstate
:inaccessiblememonly
:noub
:nortcall
:total
es una afirmación muy fuerte y probablemente ganará semánticas adicionales en futuras versiones de Julia (por ejemplo, si se agregan efectos adicionales e incluidos en la definición de :total
). Como resultado, debe usarse con cuidado. Siempre que sea posible, prefiera usar el conjunto mínimo posible de afirmaciones de efecto específicas requeridas para una aplicación particular. En casos donde se apliquen un gran número de sobrescrituras de efecto a un conjunto de funciones, se recomienda un macro personalizado sobre el uso de :total
.
Efectos negados
Los nombres de efecto pueden ser precedidos por !
para indicar que el efecto debe ser eliminado de un efecto meta anterior. Por ejemplo, :total !:nothrow
indica que, aunque la llamada es generalmente total, puede lanzar.
Managing deprecations
Base.@deprecate
— Macro@deprecate old new [export_old=true]
Desaprobación del método old
y especificar la llamada de reemplazo new
, definiendo un nuevo método old
con la firma especificada en el proceso.
Para evitar que old
sea exportado, establece export_old
en false
.
Ver también Base.depwarn()
.
A partir de Julia 1.5, las funciones definidas por @deprecate
no imprimen advertencias cuando julia
se ejecuta sin la opción --depwarn=yes
establecida, ya que el valor predeterminado de la opción --depwarn
es no
. Las advertencias se imprimen desde las pruebas ejecutadas por Pkg.test()
.
Ejemplos
julia> @deprecate old(x) new(x)
old (función genérica con 1 método)
julia> @deprecate old(x) new(x) false
old (función genérica con 1 método)
Las llamadas a @deprecate
sin anotaciones de tipo explícitas definirán métodos desaprobados que aceptan cualquier número de argumentos posicionales y de palabras clave de tipo Any
.
Los argumentos de palabras clave se reenvían cuando no hay una anotación de tipo explícita a partir de Julia 1.9. Para versiones anteriores, puedes reenviar manualmente los argumentos posicionales y de palabras clave haciendo @deprecate old(args...; kwargs...) new(args...; kwargs...)
.
Para restringir la desaprobación a una firma específica, anota los argumentos de old
. Por ejemplo,
julia> new(x::Int) = x;
julia> new(x::Float64) = 2x;
julia> @deprecate old(x::Int) new(x);
julia> methods(old)
# 1 método para la función genérica "old" de Main:
[1] old(x::Int64)
@ deprecated.jl:94
definirá y desaprobará un método old(x::Int)
que refleja new(x::Int)
pero no definirá ni desaprobará el método old(x::Float64)
.
Base.depwarn
— FunctionBase.depwarn(msg::String, funcsym::Symbol; force=false)
Imprime msg
como una advertencia de deprecación. El símbolo funcsym
debe ser el nombre de la función que llama, que se utiliza para asegurar que la advertencia de deprecación solo se imprima la primera vez para cada lugar de llamada. Establece force=true
para forzar que la advertencia siempre se muestre, incluso si Julia se inició con --depwarn=no
(el valor predeterminado).
Ver también @deprecate
.
Ejemplos
function deprecated_func()
Base.depwarn("¡No uses `deprecated_func()`!", :deprecated_func)
1 + 1
end
Missing Values
Base.Missing
— TypeFaltante
Un tipo sin campos cuya instancia única missing
se utiliza para representar valores faltantes.
Ver también: skipmissing
, nonmissingtype
, Nothing
.
Base.missing
— Constantmissing
La instancia singleton del tipo Missing
que representa un valor faltante.
Ver también: NaN
, skipmissing
, nonmissingtype
.
Base.coalesce
— Functioncoalesce(x...)
Devuelve el primer valor en los argumentos que no es igual a missing
, si lo hay. De lo contrario, devuelve missing
.
Véase también skipmissing
, something
, @coalesce
.
Ejemplos
julia> coalesce(missing, 1)
1
julia> coalesce(1, missing)
1
julia> coalesce(nothing, 1) # devuelve `nothing`
julia> coalesce(missing, missing)
missing
Base.@coalesce
— Macro@coalesce(x...)
Versión de cortocircuito de coalesce
.
Ejemplos
julia> f(x) = (println("f($x)"); missing);
julia> a = 1;
julia> a = @coalesce a f(2) f(3) error("`a` sigue siendo missing")
1
julia> b = missing;
julia> b = @coalesce b f(2) f(3) error("`b` sigue siendo missing")
f(2)
f(3)
ERROR: `b` sigue siendo missing
[...]
Este macro está disponible a partir de Julia 1.7.
Base.ismissing
— FunctionBase.skipmissing
— Functionskipmissing(itr)
Devuelve un iterador sobre los elementos en itr
omitiendo los valores missing
. El objeto devuelto se puede indexar utilizando los índices de itr
si este último es indexable. Los índices correspondientes a valores faltantes no son válidos: son omitidos por keys
y eachindex
, y se lanza una MissingException
al intentar usarlos.
Utiliza collect
para obtener un Array
que contenga los valores no missing
en itr
. Ten en cuenta que incluso si itr
es un array multidimensional, el resultado siempre será un Vector
ya que no es posible eliminar los valores faltantes mientras se preservan las dimensiones de la entrada.
Consulta también coalesce
, ismissing
, something
.
Ejemplos
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: el valor en el índice (2,) está faltando
[...]
julia> argmax(x)
3
julia> collect(keys(x))
Vector{Int64} de 2 elementos:
1
3
julia> collect(skipmissing([1, missing, 2]))
Vector{Int64} de 2 elementos:
1
2
julia> collect(skipmissing([1 missing; 2 missing]))
Vector{Int64} de 2 elementos:
1
2
Base.nonmissingtype
— Functionnonmissingtype(T::Type)
Si T
es una unión de tipos que contiene Missing
, devuelve un nuevo tipo con Missing
eliminado.
Ejemplos
julia> nonmissingtype(Union{Int64,Missing})
Int64
julia> nonmissingtype(Any)
Any
Esta función se exporta a partir de Julia 1.3.
System
Base.run
— Functionrun(command, args...; wait::Bool = true)
Ejecuta un objeto de comando, construido con comillas invertidas (ver la sección de Ejecutar Programas Externos en el manual). Lanza un error si algo sale mal, incluyendo si el proceso sale con un estado distinto de cero (cuando wait
es verdadero).
Los args...
te permiten pasar descriptores de archivo al comando, y están ordenados como descriptores de archivo unix regulares (por ejemplo stdin, stdout, stderr, FD(3), FD(4)...
).
Si wait
es falso, el proceso se ejecuta de manera asíncrona. Puedes esperar por él más tarde y verificar su estado de salida llamando a success
en el objeto de proceso devuelto.
Cuando wait
es falso, los flujos de I/O del proceso se dirigen a devnull
. Cuando wait
es verdadero, los flujos de I/O se comparten con el proceso padre. Usa pipeline
para controlar la redirección de I/O.
Base.devnull
— Constantdevnull
Utilizado en una redirección de flujo para descartar todos los datos escritos en él. Esencialmente equivalente a /dev/null
en Unix o NUL
en Windows. Uso:
run(pipeline(`cat test.txt`, devnull))
Base.success
— Functionsuccess(command)
Ejecuta un objeto de comando, construido con comillas invertidas (ver la sección Ejecutando Programas Externos en el manual), y dice si fue exitoso (salió con un código de 0). Se lanza una excepción si el proceso no se puede iniciar.
Base.process_running
— Functionprocess_running(p::Process)
Determina si un proceso se está ejecutando actualmente.
Base.process_exited
— Functionprocess_exited(p::Process)
Determina si un proceso ha salido.
Base.kill
— Methodkill(p::Process, signum=Base.SIGTERM)
Envía una señal a un proceso. El valor predeterminado es terminar el proceso. Devuelve con éxito si el proceso ya ha salido, pero lanza un error si la terminación del proceso falló por otras razones (por ejemplo, permisos insuficientes).
Base.Sys.set_process_title
— FunctionSys.set_process_title(title::AbstractString)
Establece el título del proceso. No tiene efecto en algunos sistemas operativos.
Base.Sys.get_process_title
— FunctionSys.get_process_title()
Obtiene el título del proceso. En algunos sistemas, siempre devolverá una cadena vacía.
Base.ignorestatus
— Functionignorestatus(command)
Marca un objeto de comando para que su ejecución no genere un error si el código de resultado es diferente de cero.
Base.detach
— Functiondetach(command)
Marca un objeto de comando para que se ejecute en un nuevo grupo de procesos, permitiendo que sobreviva al proceso de julia y que no se le pasen interrupciones de Ctrl-C.
Base.Cmd
— TypeCmd(cmd::Cmd; ignorestatus, detach, windows_verbatim, windows_hide, env, dir)
Cmd(exec::Vector{String})
Construye un nuevo objeto Cmd
, que representa un programa externo y argumentos, a partir de cmd
, mientras cambia la configuración de los argumentos opcionales:
ignorestatus::Bool
: Si estrue
(por defecto esfalse
), entonces elCmd
no lanzará un error si el código de retorno es diferente de cero.detach::Bool
: Si estrue
(por defecto esfalse
), entonces elCmd
se ejecutará en un nuevo grupo de procesos, permitiendo que sobreviva al procesojulia
y que no se le pase Ctrl-C.windows_verbatim::Bool
: Si estrue
(por defecto esfalse
), entonces en Windows elCmd
enviará una cadena de línea de comandos al proceso sin comillas ni escape de argumentos, incluso argumentos que contengan espacios. (En Windows, los argumentos se envían a un programa como una única cadena de "línea de comandos", y los programas son responsables de analizarla en argumentos. Por defecto, los argumentos vacíos y los argumentos con espacios o tabulaciones se citan con comillas dobles"
en la línea de comandos, y\
o"
son precedidos por barras invertidas.windows_verbatim=true
es útil para lanzar programas que analizan su línea de comandos de maneras no estándar.) No tiene efecto en sistemas que no son Windows.windows_hide::Bool
: Si estrue
(por defecto esfalse
), entonces en Windows no se muestra una nueva ventana de consola cuando se ejecuta elCmd
. Esto no tiene efecto si ya hay una consola abierta o en sistemas que no son Windows.env
: Establece las variables de entorno a utilizar al ejecutar elCmd
.env
es un diccionario que mapea cadenas a cadenas, un array de cadenas de la forma"var=val"
, un array o tupla de pares"var"=>val
. Para modificar (en lugar de reemplazar) el entorno existente, inicializaenv
concopy(ENV)
y luego estableceenv["var"]=val
según sea necesario. Para agregar a un bloque de entorno dentro de un objetoCmd
sin reemplazar todos los elementos, usaaddenv()
que devolverá un objetoCmd
con el entorno actualizado.dir::AbstractString
: Especifica un directorio de trabajo para el comando (en lugar del directorio actual).
Para cualquier palabra clave que no esté especificada, se utilizan las configuraciones actuales de cmd
.
Ten en cuenta que el constructor Cmd(exec)
no crea una copia de exec
. Cualquier cambio posterior en exec
se reflejará en el objeto Cmd
.
La forma más común de construir un objeto Cmd
es con literales de comando (comillas invertidas), por ejemplo:
`ls -l`
Esto se puede pasar al constructor Cmd
para modificar su configuración, por ejemplo:
Cmd(`echo "Hello world"`, ignorestatus=true, detach=false)
Base.setenv
— Functionsetenv(command::Cmd, env; dir)
Establece las variables de entorno que se utilizarán al ejecutar el command
dado. env
es un diccionario que mapea cadenas a cadenas, un arreglo de cadenas de la forma "var=val"
, o cero o más argumentos de pares "var"=>val
. Para modificar (en lugar de reemplazar) el entorno existente, crea env
a través de copy(ENV)
y luego establece env["var"]=val
según sea necesario, o usa addenv
.
El argumento clave dir
se puede usar para especificar un directorio de trabajo para el comando. dir
por defecto es el dir
actualmente establecido para command
(que es el directorio de trabajo actual si no se especifica ya).
Base.addenv
— Functionaddenv(command::Cmd, env...; inherit::Bool = true)
Fusiona nuevos mapeos de entorno en el objeto Cmd
dado, devolviendo un nuevo objeto Cmd
. Las claves duplicadas son reemplazadas. Si command
no contiene ningún valor de entorno establecido ya, hereda el entorno actual en el momento de la llamada a addenv()
si inherit
es true
. Las claves con valor nothing
se eliminan del entorno.
Véase también Cmd
, setenv
, ENV
.
Esta función requiere Julia 1.6 o posterior.
Base.withenv
— Functionwithenv(f, kv::Pair...)
Ejecuta f
en un entorno que se modifica temporalmente (no se reemplaza como en setenv
) por cero o más argumentos "var"=>val
kv
. withenv
se utiliza generalmente a través de la sintaxis withenv(kv...) do ... end
. Un valor de nothing
se puede usar para desactivar temporalmente una variable de entorno (si está configurada). Cuando withenv
retorna, el entorno original ha sido restaurado.
Cambiar el entorno no es seguro para hilos. Para ejecutar comandos externos con un entorno diferente al del proceso padre, se prefiere usar addenv
sobre withenv
.
Base.setcpuaffinity
— Functionsetcpuaffinity(original_command::Cmd, cpus) -> command::Cmd
Establece la afinidad de CPU del command
mediante una lista de IDs de CPU (basados en 1) cpus
. Pasar cpus = nothing
significa desactivar la afinidad de CPU si el original_command
tiene alguna.
Esta función es compatible solo en Linux y Windows. No es compatible en macOS porque libuv no admite la configuración de afinidad.
Esta función requiere al menos Julia 1.8.
Ejemplos
En Linux, se puede usar el programa de línea de comandos taskset
para ver cómo funciona setcpuaffinity
.
julia> run(setcpuaffinity(`sh -c 'taskset -p $$'`, [1, 2, 5]));
pid 2273's current affinity mask: 13
Tenga en cuenta que el valor de la máscara 13
refleja que los primeros, segundos y quintos bits (contando desde la posición menos significativa) están activados:
julia> 0b010011
0x13
Base.pipeline
— Methodpipeline(from, to, ...)
Crea un pipeline desde una fuente de datos hasta un destino. La fuente y el destino pueden ser comandos, flujos de E/S, cadenas o resultados de otras llamadas a pipeline
. Al menos un argumento debe ser un comando. Las cadenas se refieren a nombres de archivos. Cuando se llama con más de dos argumentos, se encadenan de izquierda a derecha. Por ejemplo, pipeline(a,b,c)
es equivalente a pipeline(pipeline(a,b),c)
. Esto proporciona una forma más concisa de especificar pipelines de múltiples etapas.
Ejemplos:
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)
Redirigir I/O hacia o desde el command
dado. Los argumentos de palabra clave especifican cuáles de los flujos del comando deben ser redirigidos. append
controla si la salida del archivo se agrega al archivo. Esta es una versión más general de la función pipeline
de 2 argumentos. pipeline(from, to)
es equivalente a pipeline(from, stdout=to)
cuando from
es un comando, y a pipeline(to, stdin=from)
cuando from
es otro tipo de fuente de datos.
Ejemplos:
run(pipeline(`dothings`, stdout="out.txt", stderr="errs.txt"))
run(pipeline(`update`, stdout="log.txt", append=true))
Base.Libc.gethostname
— Functiongethostname() -> String
Obtiene el nombre del host de la máquina local.
Base.Libc.getpid
— Functiongetpid() -> Int32
Obtiene el ID del proceso de Julia.
getpid(process) -> Int32
Obtiene el ID del proceso hijo, si aún existe.
Esta función requiere al menos Julia 1.1.
Base.Libc.time
— Methodtime() -> Float64
Obtiene el tiempo del sistema en segundos desde la época, con una resolución bastante alta (típicamente, microsegundos).
Base.time_ns
— Functiontime_ns() -> UInt64
Obtiene el tiempo en nanosegundos. El tiempo correspondiente a 0 es indefinido y se reinicia cada 5.8 años.
Base.@time
— Macro@time expr
@time "descripción" expr
Una macro para ejecutar una expresión, imprimiendo el tiempo que tomó ejecutarla, el número de asignaciones y el número total de bytes que su ejecución causó que se asignaran, antes de devolver el valor de la expresión. Cualquier tiempo gastado en recolección de basura (gc), compilando nuevo código, o recompilando código invalidado se muestra como un porcentaje. Cualquier conflicto de bloqueo donde un ReentrantLock
tuvo que esperar se muestra como un conteo.
Opcionalmente, proporciona una cadena de descripción para imprimir antes del informe de tiempo.
En algunos casos, el sistema mirará dentro de la expresión @time
y compilará parte del código llamado antes de que comience la ejecución de la expresión de nivel superior. Cuando eso sucede, parte del tiempo de compilación no se contará. Para incluir este tiempo, puedes ejecutar @time @eval ...
.
Consulta también @showtime
, @timev
, @timed
, @elapsed
, @allocated
, y @allocations
.
Para un benchmarking más serio, considera la macro @btime
del paquete BenchmarkTools.jl que, entre otras cosas, evalúa la función múltiples veces para reducir el ruido.
La opción de agregar una descripción se introdujo en Julia 1.8.
El tiempo de recompilación que se muestra por separado del tiempo de compilación se introdujo en Julia 1.8
El informe de cualquier conflicto de bloqueo se agregó en Julia 1.11.
julia> x = rand(10,10);
julia> @time x * x;
0.606588 segundos (2.19 M asignaciones: 116.555 MiB, 3.75% tiempo gc, 99.94% tiempo de compilación)
julia> @time x * x;
0.000009 segundos (1 asignación: 896 bytes)
julia> @time begin
sleep(0.3)
1+1
end
0.301395 segundos (8 asignaciones: 336 bytes)
2
julia> @time "Un sueño de un segundo" sleep(1)
Un sueño de un segundo: 1.005750 segundos (5 asignaciones: 144 bytes)
julia> for loop in 1:3
@time loop sleep(1)
end
1: 1.006760 segundos (5 asignaciones: 144 bytes)
2: 1.001263 segundos (5 asignaciones: 144 bytes)
3: 1.003676 segundos (5 asignaciones: 144 bytes)
Base.@showtime
— Macro@showtime expr
Como @time
pero también imprime la expresión que se está evaluando como referencia.
Este macro fue añadido en Julia 1.8.
Véase también @time
.
julia> @showtime sleep(1)
sleep(1): 1.002164 segundos (4 asignaciones: 128 bytes)
Base.@timev
— Macro@timev expr
@timev "description" expr
Esta es una versión detallada de la macro @time
. Primero imprime la misma información que @time
, luego cualquier contador de asignación de memoria no cero, y luego devuelve el valor de la expresión.
Opcionalmente, proporciona una cadena de descripción para imprimir antes del informe de tiempo.
La opción de agregar una descripción se introdujo en Julia 1.8.
Véase también @time
, @timed
, @elapsed
, @allocated
, y @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
Una macro para ejecutar una expresión y devolver el valor de la expresión, el tiempo transcurrido en segundos, el total de bytes asignados, el tiempo de recolección de basura, un objeto con varios contadores de asignación de memoria, el tiempo de compilación en segundos y el tiempo de recompilación en segundos. Cualquier conflicto de bloqueo donde un ReentrantLock
tuvo que esperar se muestra como un conteo.
En algunos casos, el sistema mirará dentro de la expresión @timed
y compilará parte del código llamado antes de que comience la ejecución de la expresión de nivel superior. Cuando eso sucede, parte del tiempo de compilación no se contará. Para incluir este tiempo, puedes ejecutar @timed @eval ...
.
Ver también @time
, @timev
, @elapsed
, @allocated
, @allocations
y @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
El tipo de retorno de esta macro se cambió de Tuple
a NamedTuple
en Julia 1.5.
Los campos lock_conflicts
, compile_time
y recompile_time
se añadieron en Julia 1.11.
Base.@elapsed
— Macro@elapsed
Una macro para evaluar una expresión, descartando el valor resultante, en su lugar devolviendo el número de segundos que tomó ejecutarse como un número de punto flotante.
En algunos casos, el sistema mirará dentro de la expresión @elapsed
y compilará parte del código llamado antes de que comience la ejecución de la expresión de nivel superior. Cuando eso sucede, parte del tiempo de compilación no se contará. Para incluir este tiempo, puedes ejecutar @elapsed @eval ...
.
Consulta también @time
, @timev
, @timed
, @allocated
, y @allocations
.
julia> @elapsed sleep(0.3)
0.301391426
Base.@allocated
— Macro@allocated
Una macro para evaluar una expresión, descartando el valor resultante, en su lugar devolviendo el número total de bytes asignados durante la evaluación de la expresión.
Véase también @allocations
, @time
, @timev
, @timed
, y @elapsed
.
julia> @allocated rand(10^6)
8000080
Base.@allocations
— Macro@allocations
Una macro para evaluar una expresión, descartar el valor resultante y, en su lugar, devolver el número total de asignaciones durante la evaluación de la expresión.
Véase también @allocated
, @time
, @timev
, @timed
y @elapsed
.
julia> @allocations rand(10^6)
2
Esta macro se agregó en Julia 1.9.
Base.@lock_conflicts
— Macro@lock_conflicts
Una macro para evaluar una expresión, descartar el valor resultante y, en su lugar, devolver el número total de conflictos de bloqueo durante la evaluación, donde un intento de bloqueo en un ReentrantLock
resultó en una espera porque el bloqueo ya estaba en uso.
Véase también @time
, @timev
y @timed
.
julia> @lock_conflicts begin
l = ReentrantLock()
Threads.@threads for i in 1:Threads.nthreads()
lock(l) do
sleep(1)
end
end
end
5
Esta macro se agregó en Julia 1.11.
Base.EnvDict
— TypeEnvDict() -> EnvDict
Un singleton de este tipo proporciona una interfaz de tabla hash a las variables de entorno.
Base.ENV
— ConstantENV
Referencia al singleton EnvDict
, que proporciona una interfaz de diccionario a las variables de entorno del sistema.
(En Windows, las variables de entorno del sistema no son sensibles a mayúsculas y minúsculas, y ENV
convierte correspondientemente todas las claves a mayúsculas para su visualización, iteración y copia. El código portátil no debe depender de la capacidad de distinguir variables por caso, y debe tener cuidado de que establecer una variable aparentemente en minúsculas puede resultar en una clave ENV
en mayúsculas.)
Mutar el entorno no es seguro para hilos.
Ejemplos
julia> ENV
Base.EnvDict con "50" entradas:
"SECURITYSESSIONID" => "123"
"USER" => "nombredeusuario"
"MallocNanoZone" => "0"
⋮ => ⋮
julia> ENV["JULIA_EDITOR"] = "vim"
"vim"
julia> ENV["JULIA_EDITOR"]
"vim"
Base.Sys.STDLIB
— ConstantSys.STDLIB::String
Una cadena que contiene la ruta completa al directorio que contiene los paquetes stdlib
.
Base.Sys.isunix
— FunctionSys.isunix([os])
Predicado para probar si el sistema operativo proporciona una interfaz similar a Unix. Consulta la documentación en Handling Operating System Variation.
Base.Sys.isapple
— FunctionSys.isapple([os])
Predicado para probar si el sistema operativo es un derivado de Apple Macintosh OS X o Darwin. Consulta la documentación en Handling Operating System Variation.
Base.Sys.islinux
— FunctionSys.islinux([os])
Predicado para probar si el sistema operativo es un derivado de Linux. Consulta la documentación en Handling Operating System Variation.
Base.Sys.isbsd
— FunctionSys.isbsd([os])
Predicado para probar si el sistema operativo es un derivado de BSD. Consulta la documentación en Handling Operating System Variation.
El núcleo de Darwin desciende de BSD, lo que significa que Sys.isbsd()
es true
en sistemas macOS. Para excluir macOS de un predicado, usa Sys.isbsd() && !Sys.isapple()
.
Base.Sys.isfreebsd
— FunctionSys.isfreebsd([os])
Predicado para probar si el sistema operativo es un derivado de FreeBSD. Consulta la documentación en Handling Operating System Variation.
No debe confundirse con Sys.isbsd()
, que es true
en FreeBSD pero también en otros sistemas basados en BSD. Sys.isfreebsd()
se refiere solo a FreeBSD.
Esta función requiere al menos Julia 1.1.
Base.Sys.isopenbsd
— FunctionSys.isopenbsd([os])
Predicado para probar si el sistema operativo es un derivado de OpenBSD. Consulta la documentación en Handling Operating System Variation.
No debe confundirse con Sys.isbsd()
, que es true
en OpenBSD pero también en otros sistemas basados en BSD. Sys.isopenbsd()
se refiere únicamente a OpenBSD.
Esta función requiere al menos Julia 1.1.
Base.Sys.isnetbsd
— FunctionSys.isnetbsd([os])
Predicado para probar si el sistema operativo es un derivado de NetBSD. Consulta la documentación en Handling Operating System Variation.
No debe confundirse con Sys.isbsd()
, que es true
en NetBSD pero también en otros sistemas basados en BSD. Sys.isnetbsd()
se refiere únicamente a NetBSD.
Esta función requiere al menos Julia 1.1.
Base.Sys.isdragonfly
— FunctionSys.isdragonfly([os])
Predicado para probar si el sistema operativo es un derivado de DragonFly BSD. Consulta la documentación en Handling Operating System Variation.
No debe confundirse con Sys.isbsd()
, que es true
en DragonFly pero también en otros sistemas basados en BSD. Sys.isdragonfly()
se refiere únicamente a DragonFly.
Esta función requiere al menos Julia 1.1.
Base.Sys.iswindows
— FunctionSys.iswindows([os])
Predicado para probar si el sistema operativo es un derivado de Microsoft Windows NT. Consulta la documentación en Handling Operating System Variation.
Base.Sys.windows_version
— FunctionSys.windows_version()
Devuelve el número de versión del núcleo de Windows NT como un VersionNumber
, es decir, v"mayor.menor.construcción"
, o v"0.0.0"
si esto no se está ejecutando en Windows.
Base.Sys.free_memory
— FunctionSys.free_memory()
Obtiene la memoria total libre en RAM en bytes.
Base.Sys.total_memory
— FunctionSys.total_memory()
Obtiene la memoria total en RAM (incluyendo la que se está utilizando actualmente) en bytes. Esta cantidad puede estar restringida, por ejemplo, por los grupos de control de Linux. Para la cantidad sin restricciones, consulte Sys.total_physical_memory()
.
Base.Sys.free_physical_memory
— FunctionSys.free_physical_memory()
Obtiene la memoria libre del sistema en bytes. La cantidad total puede no estar disponible para el proceso actual; utiliza Sys.free_memory()
para la cantidad realmente disponible.
Base.Sys.total_physical_memory
— FunctionSys.total_physical_memory()
Obtiene la memoria total en RAM (incluyendo la que está actualmente en uso) en bytes. La cantidad total puede no estar disponible para el proceso actual; consulta Sys.total_memory()
.
Base.Sys.uptime
— FunctionSys.uptime()
Obtiene el tiempo de actividad actual del sistema en segundos.
Base.Sys.isjsvm
— FunctionSys.isjsvm([os])
Predicado para probar si Julia se está ejecutando en una máquina virtual de JavaScript (JSVM), incluyendo, por ejemplo, una incrustación de JavaScript de WebAssembly en un navegador web.
Esta función requiere al menos Julia 1.2.
Base.Sys.loadavg
— FunctionSys.loadavg()
Obtiene el promedio de carga. Ver: https://en.wikipedia.org/wiki/Load_(computing).
Base.Sys.isexecutable
— Functionisexecutable(path::String)
Devuelve true
si el path
dado tiene permisos de ejecución.
Este permiso puede cambiar antes de que el usuario ejecute path
, por lo que se recomienda ejecutar el archivo y manejar el error si eso falla, en lugar de llamar a isexecutable
primero.
Antes de Julia 1.6, esto no interrogaba correctamente los ACL del sistema de archivos en Windows, por lo que devolvería true
para cualquier archivo. A partir de Julia 1.6, determina correctamente si el archivo está marcado como ejecutable o no.
Véase también ispath
, isreadable
, iswritable
.
Base.Sys.isreadable
— Functionisreadable(path::String)
Devuelve true
si los permisos de acceso para la ruta
dada permiten la lectura por parte del usuario actual.
Este permiso puede cambiar antes de que el usuario llame a open
, por lo que se recomienda simplemente llamar a open
solo y manejar el error si eso falla, en lugar de llamar a isreadable
primero.
Actualmente, esta función no interroga correctamente los ACL del sistema de archivos en Windows, por lo que puede devolver resultados incorrectos.
Esta función requiere al menos Julia 1.11.
Véase también ispath
, isexecutable
, iswritable
. ```
isreadable(io) -> Bool
Devuelve false
si el objeto IO especificado no es legible.
Ejemplos
julia> open("myfile.txt", "w") do io
print(io, "¡Hola mundo!");
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)
Devuelve true
si los permisos de acceso para la ruta
dada permiten la escritura por parte del usuario actual.
Este permiso puede cambiar antes de que el usuario llame a open
, por lo que se recomienda simplemente llamar a open
solo y manejar el error si falla, en lugar de llamar a iswritable
primero.
Actualmente, esta función no interroga correctamente los ACL del sistema de archivos en Windows, por lo que puede devolver resultados incorrectos.
Esta función requiere al menos Julia 1.11.
Véase también ispath
, isexecutable
, isreadable
.
iswritable(io) -> Bool
Devuelve false
si el objeto IO especificado no es escribible.
Ejemplos
julia> open("myfile.txt", "w") do io
print(io, "¡Hola mundo!");
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
Devuelve el nombre de usuario del usuario actual. Si no se puede determinar el nombre de usuario o está vacío, esta función lanza un error.
Para recuperar un nombre de usuario que se puede sobrescribir a través de una variable de entorno, por ejemplo, USER
, considera usar
user = get(Sys.username, ENV, "USER")
Esta función requiere al menos Julia 1.11.
Consulta también homedir
.
Base.@static
— Macro@static
Evalúa parcialmente una expresión en el tiempo de análisis.
Por ejemplo, @static Sys.iswindows() ? foo : bar
evaluará Sys.iswindows()
e insertará ya sea foo
o bar
en la expresión. Esto es útil en casos donde un constructo sería inválido en otras plataformas, como un ccall
a una función inexistente. @static if Sys.isapple() foo end
y @static foo <&&,||> bar
también son sintaxis válidas.
Versioning
Base.VersionNumber
— TypeVersionNumber
Tipo de número de versión que sigue las especificaciones de versionado semántico (semver), compuesto por valores numéricos mayor, menor y de parche, seguidos de anotaciones alfanuméricas de pre-lanzamiento y construcción.
Los objetos VersionNumber
se pueden comparar con todos los operadores de comparación estándar (==
, <
, <=
, etc.), con el resultado siguiendo las reglas de semver.
VersionNumber
tiene los siguientes campos públicos:
v.major::Integer
v.minor::Integer
v.patch::Integer
v.prerelease::Tuple{Vararg{Union{Integer, AbstractString}}}
v.build::Tuple{Vararg{Union{Integer, AbstractString}}}
Véase también @v_str
para construir de manera eficiente objetos VersionNumber
a partir de cadenas literales en formato semver, VERSION
para el VersionNumber
de Julia en sí, y Literales de Números de Versión en el manual.
Ejemplos
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
Macro de cadena utilizado para analizar una cadena a un VersionNumber
.
Ejemplos
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)
Lanza un ErrorException
con el mensaje dado.
error(msg...)
Lanza un ErrorException
con un mensaje construido por string(msg...)
.
Core.throw
— FunctionBase.rethrow
— Functionrethrow()
Vuelve a lanzar la excepción actual desde dentro de un bloque catch
. La excepción relanzada continuará propagándose como si no hubiera sido capturada.
La forma alternativa rethrow(e)
te permite asociar un objeto de excepción alternativo e
con la traza de pila actual. Sin embargo, esto tergiversa el estado del programa en el momento del error, por lo que se te anima a lanzar una nueva excepción usando throw(e)
. En Julia 1.1 y versiones posteriores, usar throw(e)
preservará la excepción raíz en la pila, como se describe en current_exceptions
.
Base.backtrace
— Functionbacktrace()
Obtiene un objeto de backtrace para el punto actual del programa.
Base.catch_backtrace
— Functioncatch_backtrace()
Obtiene el backtrace de la excepción actual, para usar dentro de bloques catch
.
Base.current_exceptions
— Functioncurrent_exceptions(task::Task=current_task(); [backtrace::Bool=true])
Obtiene la pila de excepciones que se están manejando actualmente. Para bloques de captura anidados, puede haber más de una excepción actual, en cuyo caso la excepción lanzada más recientemente está al final de la pila. La pila se devuelve como un ExceptionStack
, que es un AbstractVector de tuplas nombradas (exception,backtrace)
. Si backtrace
es falso, la traza de la pila en cada par se establecerá en nothing
.
Pasar explícitamente task
devolverá la pila de excepciones actual en una tarea arbitraria. Esto es útil para inspeccionar tareas que han fallado debido a excepciones no capturadas.
Esta función se conocía con el nombre experimental catch_stack()
en Julia 1.1–1.6, y tenía un tipo de retorno de Vector de tuplas simple.
Base.@assert
— Macro@assert cond [texto]
Lanza un AssertionError
si cond
es false
. Esta es la sintaxis preferida para escribir afirmaciones, que son condiciones que se asumen como verdaderas, pero que el usuario podría decidir verificar de todos modos, como una ayuda para la depuración si fallan. El mensaje opcional texto
se muestra al fallar la afirmación.
Una afirmación podría estar deshabilitada en algunos niveles de optimización. Por lo tanto, las afirmaciones solo deben usarse como una herramienta de depuración y no deben usarse para la verificación de autenticación (por ejemplo, verificar contraseñas o comprobar límites de arreglos). El código no debe depender de los efectos secundarios de ejecutar cond
para el comportamiento correcto de una función.
Ejemplos
julia> @assert iseven(3) "¡3 es un número impar!"
ERROR: AssertionError: 3 es un número impar!
julia> @assert isodd(3) "¿Qué son los números pares?"
Base.Experimental.register_error_hint
— FunctionExperimental.register_error_hint(handler, exceptiontype)
Registra una función de "sugerencia" handler(io, exception)
que puede sugerir formas potenciales para que los usuarios eviten errores. handler
debe examinar exception
para ver si se cumplen las condiciones apropiadas para una sugerencia y, de ser así, generar salida a io
. Los paquetes deben llamar a register_error_hint
desde dentro de su función __init__
.
Para tipos de excepciones específicos, se requiere que handler
acepte argumentos adicionales:
MethodError
: proporcionarhandler(io, exc::MethodError, argtypes, kwargs)
, que divide los argumentos combinados en argumentos posicionales y de palabra clave.
Al emitir una sugerencia, la salida debe comenzar típicamente con \n
.
Si defines tipos de excepciones personalizados, tu método showerror
puede soportar sugerencias llamando a Experimental.show_error_hints
.
Ejemplos
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
# El color no es necesario, esto es solo para mostrar que es posible.
print(io, "\n¿Quisiste llamar a ")
printstyled(io, "`any_number`?", color=:cyan)
end
end
end
end
Entonces, si llamas a Hinter.only_int
con algo que no es un Int
(activando así un MethodError
), emite la sugerencia:
julia> Hinter.only_int(1.0)
ERROR: MethodError: no method matching only_int(::Float64)
La función `only_int` existe, pero no se define ningún método para esta combinación de tipos de argumento.
¿Quisiste llamar a `any_number`?
Los candidatos más cercanos son:
...
Las sugerencias de error personalizadas están disponibles a partir de Julia 1.5.
Esta interfaz es experimental y está sujeta a cambios o eliminación sin previo aviso. Para protegerte contra cambios, considera poner cualquier registro dentro de un bloque if isdefined(Base.Experimental, :register_error_hint) ... end
.
Base.Experimental.show_error_hints
— FunctionExperimental.show_error_hints(io, ex, args...)
Invoca todos los controladores de Experimental.register_error_hint
para el tipo de excepción particular typeof(ex)
. args
debe contener cualquier otro argumento esperado por el controlador para ese tipo.
Las sugerencias de error personalizadas están disponibles a partir de Julia 1.5.
Esta interfaz es experimental y está sujeta a cambios o eliminación sin previo aviso.
Core.ArgumentError
— TypeArgumentError(msg)
Los argumentos pasados a una función son inválidos. msg
es un mensaje de error descriptivo.
Core.AssertionError
— TypeAssertionError([msg])
La condición afirmada no se evaluó como true
. El argumento opcional msg
es una cadena de error descriptiva.
Ejemplos
julia> @assert false "esto no es verdad"
ERROR: AssertionError: esto no es verdad
AssertionError
generalmente se lanza desde @assert
. ```
Core.BoundsError
— TypeBoundsError([a],[i])
Una operación de indexación en un arreglo, a
, intentó acceder a un elemento fuera de los límites en el índice i
.
Ejemplos
julia> A = fill(1.0, 7);
julia> A[8]
ERROR: BoundsError: intento de acceder a un Vector{Float64} de 7 elementos en el índice [8]
julia> B = fill(1.0, (2,3));
julia> B[2, 4]
ERROR: BoundsError: intento de acceder a una Matriz{Float64} de 2×3 en el índice [2, 4]
julia> B[9]
ERROR: BoundsError: intento de acceder a una Matriz{Float64} de 2×3 en el índice [9]
Base.CompositeException
— TypeCompositeException
Envuelve un Vector
de excepciones lanzadas por una Task
(por ejemplo, generadas por un trabajador remoto a través de un canal o una escritura de E/S local que se ejecuta de forma asíncrona o un trabajador remoto bajo pmap
) con información sobre la serie de excepciones. Por ejemplo, si un grupo de trabajadores está ejecutando varias tareas y múltiples trabajadores fallan, el CompositeException
resultante contendrá un "paquete" de información de cada trabajador que indica dónde y por qué ocurrieron las excepciones.
Base.DimensionMismatch
— TypeDimensionMismatch([msg])
Los objetos llamados no tienen una dimensionalidad coincidente. El argumento opcional msg
es una cadena de error descriptiva.
Core.DivideError
— TypeDivideError()
Se intentó una división entera con un valor de denominador de 0.
Ejemplos
julia> 2/0
Inf
julia> div(2, 0)
ERROR: DivideError: error de división entera
Stacktrace:
[...]
Core.DomainError
— TypeDomainError(val)
DomainError(val, msg)
El argumento val
a una función o constructor está fuera del dominio válido.
Ejemplos
julia> sqrt(-1)
ERROR: DomainError con -1.0:
sqrt fue llamado con un argumento real negativo pero solo devolverá un resultado complejo si se llama con un argumento complejo. Intenta sqrt(Complex(x)).
Stacktrace:
[...]
Base.EOFError
— TypeEOFError()
No hay más datos disponibles para leer de un archivo o flujo.
Core.ErrorException
— TypeErrorException(msg)
Tipo de error genérico. El mensaje de error, en el campo .msg
, puede proporcionar detalles más específicos.
Ejemplos
julia> ex = ErrorException("He hecho algo malo");
julia> ex.msg
"He hecho algo malo"
Core.InexactError
— TypeInexactError(nombre::Symbol, T, val)
No se puede convertir exactamente val
al tipo T
en un método de la función nombre
.
Ejemplos
julia> convert(Float64, 1+2im)
ERROR: InexactError: Float64(1 + 2im)
Stacktrace:
[...]
Core.InterruptException
— TypeInterruptException()
El proceso fue detenido por una interrupción del terminal (CTRL+C).
Tenga en cuenta que, en un script de Julia iniciado sin la opción -i
(interactiva), InterruptException
no se lanza por defecto. Llamar a Base.exit_on_sigint(false)
en el script puede recuperar el comportamiento del REPL. Alternativamente, un script de Julia se puede iniciar con
julia -e "include(popfirst!(ARGS))" script.jl
para permitir que InterruptException
se lance por CTRL+C durante la ejecución.
Base.KeyError
— TypeKeyError(key)
Una operación de indexación en un AbstractDict
(Dict
) o un objeto tipo Set
intentó acceder o eliminar un elemento que no existe.
Core.LoadError
— TypeLoadError(file::AbstractString, line::Int, error)
Ocurrió un error mientras se include
, require
o using
un archivo. Los detalles del error deberían estar disponibles en el campo .error
.
Los LoadErrors ya no se emiten por @macroexpand
, @macroexpand1
y `macroexpand a partir de Julia 1.7.
Core.MethodError
— TypeMethodError(f, args)
No existe un método con la firma de tipo requerida en la función genérica dada. Alternativamente, no hay un método más específico único.
Base.MissingException
— TypeMissingException(msg)
Excepción lanzada cuando se encuentra un valor missing
en una situación donde no es compatible. El mensaje de error, en el campo msg
, puede proporcionar detalles más específicos.
Core.OutOfMemoryError
— TypeOutOfMemoryError()
Una operación asignó demasiada memoria para que el sistema o el recolector de basura pudieran manejarla adecuadamente.
Core.ReadOnlyMemoryError
— TypeReadOnlyMemoryError()
Una operación intentó escribir en una memoria que es de solo lectura.
Core.OverflowError
— TypeOverflowError(msg)
El resultado de una expresión es demasiado grande para el tipo especificado y causará un desbordamiento.
Base.ProcessFailedException
— TypeProcessFailedException
Indica un estado de salida problemático de un proceso. Al ejecutar comandos o tuberías, esto se lanza para indicar que se devolvió un código de salida distinto de cero (es decir, que el proceso invocado falló).
Base.TaskFailedException
— TypeTaskFailedException
Esta excepción es lanzada por una llamada a wait(t)
cuando la tarea t
falla. TaskFailedException
envuelve la tarea fallida t
.
Core.StackOverflowError
— TypeStackOverflowError()
La llamada a la función creció más allá del tamaño de la pila de llamadas. Esto suele suceder cuando una llamada se recursiona infinitamente.
Base.SystemError
— TypeSystemError(prefix::AbstractString, [errno::Int32])
Una llamada al sistema falló con un código de error (en la variable global errno
).
Core.TypeError
— TypeTypeError(func::Symbol, context::AbstractString, expected::Type, got)
Una falla de afirmación de tipo, o llamar a una función intrínseca con un tipo de argumento incorrecto.
Core.UndefKeywordError
— TypeUndefKeywordError(var::Symbol)
El argumento de palabra clave requerido var
no fue asignado en una llamada a función.
Ejemplos
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()
El ítem o campo no está definido para el objeto dado.
Ejemplos
julia> struct MyType
a::Vector{Int}
MyType() = new()
end
julia> A = MyType()
MyType(#undef)
julia> A.a
ERROR: UndefRefError: acceso a referencia indefinida
Stacktrace:
[...]
Core.UndefVarError
— TypeUndefVarError(var::Symbol, [scope])
Un símbolo en el ámbito actual no está definido.
Ejemplos
julia> a
ERROR: UndefVarError: `a` no definido en `Main`
julia> a = 1;
julia> a
1
Base.StringIndexError
— TypeStringIndexError(str, i)
Se produjo un error al intentar acceder a str
en el índice i
que no es válido.
Core.InitError
— TypeInitError(mod::Symbol, error)
Ocurrió un error al ejecutar la función __init__
de un módulo. El error real lanzado está disponible en el campo .error
.
Base.retry
— Functionretry(f; delays=ExponentialBackOff(), check=nothing) -> Function
Devuelve una función anónima que llama a la función f
. Si se produce una excepción, f
se vuelve a llamar repetidamente, cada vez que check
devuelve true
, después de esperar el número de segundos especificado en delays
. check
debe ingresar el estado actual de delays
y la Exception
.
Antes de Julia 1.2, esta firma estaba restringida a f::Function
.
Ejemplos
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)
Un iterador de Float64
de longitud n
cuyos elementos aumentan exponencialmente a una tasa en el intervalo factor
* (1 ± jitter
). El primer elemento es first_delay
y todos los elementos están limitados a max_delay
.
Events
Base.Timer
— MethodTimer(callback::Function, delay; interval = 0)
Crea un temporizador que ejecuta la función callback
en cada expiración del temporizador.
Las tareas en espera se despiertan y la función callback
se llama después de un retraso inicial de delay
segundos, y luego se repite con el intervalo dado en segundos. Si interval
es igual a 0
, el callback solo se ejecuta una vez. La función callback
se llama con un solo argumento, el temporizador en sí. Detén un temporizador llamando a close
. El callback
puede seguir ejecutándose una vez más, si el temporizador ya ha expirado.
Ejemplos
Aquí el primer número se imprime después de un retraso de dos segundos, luego los números siguientes se imprimen rápidamente.
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
— TypeTimer(delay; interval = 0)
Crea un temporizador que despierta tareas que están esperando por él (llamando a wait
en el objeto temporizador).
Las tareas en espera se despiertan después de un retraso inicial de al menos delay
segundos, y luego se repiten después de que transcurran al menos interval
segundos nuevamente. Si interval
es igual a 0
, el temporizador solo se activa una vez. Cuando el temporizador se cierra (mediante close
), las tareas en espera se despiertan con un error. Usa isopen
para verificar si un temporizador sigue activo.
interval
está sujeto a la acumulación de desajuste de tiempo. Si necesitas eventos precisos en un momento absoluto particular, crea un nuevo temporizador en cada expiración con la diferencia hasta el siguiente tiempo calculada.
Un Timer
requiere puntos de ceder para actualizar su estado. Por ejemplo, isopen(t::Timer)
no se puede usar para hacer un timeout en un bucle while que no cede.
Base.AsyncCondition
— TypeAsyncCondition()
Crea una condición asíncrona que despierta tareas que están esperando por ella (llamando a wait
en el objeto) cuando se notifica desde C mediante una llamada a uv_async_send
. Las tareas en espera se despiertan con un error cuando el objeto se cierra (mediante close
). Usa isopen
para verificar si todavía está activa.
Esto proporciona un orden de memoria implícito de adquisición y liberación entre los hilos que envían y los que esperan.
Base.AsyncCondition
— MethodAsyncCondition(callback::Function)
Crea una condición asíncrona que llama a la función callback
dada. El callback
recibe un argumento, el objeto de condición asíncrona en sí.
Reflection
Base.nameof
— Methodnameof(m::Module) -> Symbol
Obtiene el nombre de un Module
como un Symbol
.
Ejemplos
julia> nameof(Base.Broadcast)
:Broadcast
Base.parentmodule
— Functionparentmodule(m::Module) -> Module
Obtiene el Module
que encierra a un módulo. Main
es su propio padre.
Véase también: names
, nameof
, fullname
, @__MODULE__
.
Ejemplos
julia> parentmodule(Main)
Main
julia> parentmodule(Base.Broadcast)
Base
parentmodule(t::DataType) -> Module
Determina el módulo que contiene la definición de un DataType
(potencialmente envuelto en UnionAll
).
Ejemplos
julia> module Foo
struct Int end
end
Foo
julia> parentmodule(Int)
Core
julia> parentmodule(Foo.Int)
Foo
parentmodule(f::Function) -> Module
Determina el módulo que contiene la (primera) definición de una función genérica.
parentmodule(f::Function, types) -> Module
Determina el módulo que contiene el primer método de una función genérica f
que coincide con los tipos especificados.
parentmodule(m::Method) -> Module
Devuelve el módulo en el que se define el método dado m
.
Pasar un Method
como argumento requiere Julia 1.9 o posterior.
Base.pathof
— Methodpathof(m::Module)
Devuelve la ruta del archivo m.jl
que se utilizó para importar
el módulo m
, o nada
si m
no fue importado de un paquete.
Utiliza dirname
para obtener la parte del directorio y basename
para obtener la parte del nombre del archivo de la ruta.
Ver también pkgdir
.
Base.pkgdir
— Methodpkgdir(m::Module[, paths::String...])
Devuelve el directorio raíz del paquete que declaró el módulo m
, o nothing
si m
no fue declarado en un paquete. Opcionalmente, se pueden proporcionar cadenas de componentes de ruta adicionales para construir una ruta dentro del directorio raíz del paquete.
Para obtener el directorio raíz del paquete que implementa el módulo actual, se puede usar la forma pkgdir(@__MODULE__)
.
Si se proporciona un módulo de extensión, se devuelve la raíz del paquete padre.
julia> pkgdir(Foo)
"/path/to/Foo.jl"
julia> pkgdir(Foo, "src", "file.jl")
"/path/to/Foo.jl/src/file.jl"
Ver también pathof
.
El argumento opcional paths
requiere al menos Julia 1.7.
Base.pkgversion
— Methodpkgversion(m::Module)
Devuelve la versión del paquete que importó el módulo m
, o nothing
si m
no fue importado de un paquete, o importado de un paquete sin un campo de versión establecido.
La versión se lee del Project.toml del paquete durante la carga del paquete.
Para obtener la versión del paquete que importó el módulo actual, se puede usar la forma pkgversion(@__MODULE__)
.
Esta función fue introducida en Julia 1.9.
Base.moduleroot
— Functionmoduleroot(m::Module) -> Module
Encuentra el módulo raíz de un módulo dado. Este es el primer módulo en la cadena de módulos padre de m
que es un módulo raíz registrado o que es su propio módulo padre.
__module__
— Keyword__module__
El argumento __module__
solo es visible dentro de la macro y proporciona información (en forma de un objeto Module
) sobre el contexto de expansión de la invocación de la macro. Consulte la sección del manual sobre Invocación de macros para más información.
__source__
— Keyword__source__
El argumento __source__
solo es visible dentro de la macro y proporciona información (en forma de un objeto LineNumberNode
) sobre la ubicación del analizador del signo @
a partir de la invocación de la macro. Consulte la sección del manual sobre Invocación de macros para más información.
Base.@__MODULE__
— Macro@__MODULE__ -> Módulo
Obtiene el Módulo
de la evaluación de nivel superior, que es el Módulo
del cual se está leyendo actualmente el código.
Base.@__FILE__
— Macro@__FILE__ -> String
Expande a una cadena con la ruta al archivo que contiene la llamada a la macro, o una cadena vacía si se evalúa con julia -e <expr>
. Devuelve nothing
si la macro no tenía información de origen del analizador. Alternativamente, consulta PROGRAM_FILE
.
Base.@__DIR__
— Macro@__DIR__ -> String
Macro para obtener la ruta absoluta del directorio actual como una cadena.
Si se encuentra en un script, devuelve el directorio del script que contiene la llamada a la macro @__DIR__
. Si se ejecuta desde un REPL o si se evalúa con julia -e <expr>
, devuelve el directorio de trabajo actual.
Ejemplos
El ejemplo ilustra la diferencia en los comportamientos de @__DIR__
y pwd()
, creando un script simple en un directorio diferente al directorio de trabajo actual y ejecutando ambos comandos:
julia> cd("/home/JuliaUser") # directorio de trabajo
julia> # crear script en /home/JuliaUser/Projects
open("/home/JuliaUser/Projects/test.jl","w") do io
print(io, """
println("@__DIR__ = ", @__DIR__)
println("pwd() = ", pwd())
""")
end
julia> # salida del directorio del script y del directorio de trabajo actual
include("/home/JuliaUser/Projects/test.jl")
@__DIR__ = /home/JuliaUser/Projects
pwd() = /home/JuliaUser
Base.@__LINE__
— Macro@__LINE__ -> Int
Expande al número de línea de la ubicación de la llamada al macro. Devuelve 0
si no se pudo determinar el número de línea.
Base.fullname
— Functionfullname(m::Module)
Obtiene el nombre completamente calificado de un módulo como una tupla de símbolos. Por ejemplo,
Ejemplos
julia> fullname(Base.Iterators)
(:Base, :Iterators)
julia> fullname(Main)
(:Main,)
Base.names
— Functionnames(x::Module; all::Bool = false, imported::Bool = false)
Obtiene un vector de los nombres públicos de un Module
, excluyendo los nombres obsoletos. Si all
es verdadero, entonces la lista también incluye nombres no públicos definidos en el módulo, nombres obsoletos y nombres generados por el compilador. Si imported
es verdadero, entonces los nombres importados explícitamente de otros módulos también se incluyen. Los nombres se devuelven en orden alfabético.
Como un caso especial, todos los nombres definidos en Main
se consideran "públicos", ya que no es idiomático marcar explícitamente los nombres de Main
como públicos.
sym ∈ names(SomeModule)
no implica isdefined(SomeModule, sym)
. names
devolverá símbolos marcados con public
o export
, incluso si no están definidos en el módulo.
Véase también: Base.isexported
, Base.ispublic
, Base.@locals
, @__MODULE__
.
Base.isexported
— Functionisexported(m::Module, s::Symbol) -> Bool
Devuelve si un símbolo está exportado desde un módulo.
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
Devuelve si un símbolo está marcado como público en un módulo.
Los símbolos exportados se consideran públicos.
Esta función y la noción de publicidad se añadieron en Julia 1.11.
Véase también: 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
Obtiene el nombre de una Function
genérica como un símbolo. Para funciones anónimas, este es un nombre generado por el compilador. Para subtipos de Function
declarados explícitamente, es el nombre del tipo de la función.
Base.functionloc
— Methodfunctionloc(f::Function, types)
Devuelve una tupla (nombre_archivo, línea)
que da la ubicación de una definición de Function
genérica.
Base.functionloc
— Methodfunctionloc(m::Method)
Devuelve una tupla (nombre_archivo, línea)
que da la ubicación de una definición de Method
.
Base.@locals
— Macro@locals()
Construye un diccionario de los nombres (como símbolos) y valores de todas las variables locales definidas en el sitio de llamada.
Este macro requiere al menos Julia 1.1.
Ejemplos
julia> let x = 1, y = 2
Base.@locals
end
Dict{Symbol, Any} con 2 entradas:
: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])
Recupera el valor de la vinculación name
del módulo module
. Opcionalmente, se puede definir un orden atómico para la operación; de lo contrario, se predetermina a monotónico.
Si bien el acceso a las vinculaciones del módulo utilizando getfield
sigue siendo compatible, se debe preferir siempre el uso de getglobal
, ya que getglobal
permite el control sobre el orden atómico (getfield
es siempre monotónico) y significa mejor la intención del código tanto para el usuario como para el compilador.
La mayoría de los usuarios no deberían tener que llamar a esta función directamente. La función getproperty
o la sintaxis correspondiente (es decir, module.name
) deberían ser preferidas en todos menos en unos pocos casos de uso muy específicos.
Esta función requiere Julia 1.9 o posterior.
Véase también getproperty
y setglobal!
.
Ejemplos
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])
Establece o cambia el valor de la vinculación name
en el módulo module
a x
. No se realiza conversión de tipo, por lo que si ya se ha declarado un tipo para la vinculación, x
debe ser del tipo apropiado o se lanzará un error.
Además, se puede especificar un orden atómico para esta operación; de lo contrario, por defecto es monotónico.
Los usuarios normalmente accederán a esta funcionalidad a través de la función setproperty!
o la sintaxis correspondiente (es decir, module.name = x
), por lo que esto está destinado solo a casos de uso muy específicos.
Esta función requiere Julia 1.9 o posterior.
Véase también setproperty!
y getglobal
Ejemplos
julia> module M; global a; end;
julia> M.a # igual que `getglobal(M, :a)`
ERROR: UndefVarError: `a` no definido en `M`
Sugerencia: añade una importación o asignación apropiada. Esta global fue declarada pero no asignada.
Stacktrace:
[1] getproperty(x::Module, f::Symbol)
@ Base ./Base.jl:42
[2] top-level scope
@ 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
Realiza de manera atómica las operaciones para obtener y establecer un global después de aplicar la función op
.
Esta función requiere Julia 1.11 o posterior.
Véase también modifyproperty!
y setglobal!
.
Core.swapglobal!
— Functionswapglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])
Realiza atómicamente las operaciones para obtener y establecer simultáneamente un global.
Esta función requiere Julia 1.11 o posterior.
Véase también swapproperty!
y setglobal!
.
Core.setglobalonce!
— Functionsetglobalonce!(module::Module, name::Symbol, value,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool
Realiza atómicamente las operaciones para establecer un global a un valor dado, solo si no se había establecido previamente.
Esta función requiere Julia 1.11 o posterior.
Véase también setpropertyonce!
y setglobal!
.
Core.replaceglobal!
— Functionreplaceglobal!(module::Module, name::Symbol, expected, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)
Realiza atómicamente las operaciones para obtener y establecer condicionalmente un global a un valor dado.
Esta función requiere Julia 1.11 o posterior.
Véase también replaceproperty!
y setglobal!
.
Documentation
(Véase también el capítulo documentation.)
Core.@doc
— MacroDocumentación
Las funciones, métodos y tipos pueden ser documentados colocando una cadena antes de la definición:
"""
# La Función Foo
`foo(x)`: Foo la vida de `x`.
"""
foo(x) = ...
El macro @doc
se puede usar directamente para establecer y recuperar documentación / metadatos. El macro tiene un análisis especial para que el objeto documentado pueda aparecer en la siguiente línea:
@doc "blah"
function foo() ...
Por defecto, la documentación se escribe en Markdown, pero cualquier objeto puede ser utilizado como el primer argumento.
Documentando objetos por separado de sus definiciones
Puedes documentar un objeto antes o después de su definición con
@doc "foo" function_to_doc
@doc "bar" TypeToDoc
Para macros, la sintaxis es @doc "macro doc" :(Module.@macro)
o @doc "macro doc" :(string_macro"")
para macros de cadena. Sin la comilla :()
la expansión de la macro será documentada.
Recuperando Documentación
Puedes recuperar docs para funciones, macros y otros objetos de la siguiente manera:
@doc foo
@doc @time
@doc md""
Funciones y Métodos
Colocar documentación antes de una definición de método (por ejemplo, function foo() ...
o foo() = ...
) hará que ese método específico sea documentado, en lugar de toda la función. Los docs de los métodos se concatenan en el orden en que fueron definidos para proporcionar docs para la función.
Base.Docs.HTML
— TypeHTML(s)
: Crea un objeto que renderiza s
como html.
HTML("<div>foo</div>")
También puedes usar un flujo para grandes cantidades de datos:
HTML() do io
println(io, "<div>foo</div>")
end
HTML
se exporta actualmente para mantener la compatibilidad hacia atrás, pero esta exportación está en desuso. Se recomienda usar este tipo como Docs.HTML
o importarlo explícitamente desde Docs
.
Base.Docs.Text
— TypeText(s)
: Crea un objeto que renderiza s
como texto plano.
Text("foo")
También puedes usar un flujo para grandes cantidades de datos:
Text() do io
println(io, "foo")
end
Text
se exporta actualmente para mantener la compatibilidad hacia atrás, pero esta exportación está en desuso. Se recomienda usar este tipo como Docs.Text
o importarlo explícitamente desde Docs
.
Base.Docs.hasdoc
— FunctionDocs.hasdoc(mod::Module, sym::Symbol)::Bool
Devuelve true
si sym
en mod
tiene una cadena de documentación y false
en caso contrario.
Base.Docs.undocumented_names
— Functionundocumented_names(mod::Module; private=false)
Devuelve un vector ordenado de símbolos no documentados en module
(es decir, que carecen de cadenas de documentación). private=false
(el valor predeterminado) devuelve solo identificadores declarados con public
y/o export
, mientras que private=true
devuelve todos los símbolos en el módulo (excluyendo los símbolos ocultos generados por el compilador que comienzan con #
).
Véase también: 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}
Identifica el paquete por su nombre desde la pila del entorno actual, devolviendo su PkgId
, o nothing
si no se puede encontrar.
Si solo se proporciona el argumento name
, busca en cada entorno de la pila y sus dependencias directas nombradas.
El argumento where
proporciona el contexto desde donde buscar el paquete: en este caso, primero verifica si el nombre coincide con el contexto mismo, de lo contrario, busca todas las dependencias recursivas (del manifiesto resuelto de cada entorno) hasta localizar el contexto where
, y desde allí identifica la dependencia con el nombre correspondiente.
julia> Base.identify_package("Pkg") # Pkg es una dependencia del entorno por defecto
Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]
julia> using LinearAlgebra
julia> Base.identify_package(LinearAlgebra, "Pkg") # Pkg no es una dependencia de LinearAlgebra
Base.locate_package
— FunctionBase.locate_package(pkg::PkgId)::Union{String, Nothing}
La ruta al archivo de punto de entrada para el paquete correspondiente al identificador pkg
, o nothing
si no se encuentra. Ver también 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)
Esta función es parte de la implementación de using
/ import
, si un módulo no está ya definido en Main
. También se puede llamar directamente para forzar la recarga de un módulo, independientemente de si se ha cargado antes (por ejemplo, al desarrollar bibliotecas de forma interactiva).
Carga un archivo fuente, en el contexto del módulo Main
, en cada nodo activo, buscando en ubicaciones estándar para archivos. require
se considera una operación de nivel superior, por lo que establece la ruta de include
actual pero no la utiliza para buscar archivos (ver ayuda para include
). Esta función se utiliza típicamente para cargar código de biblioteca y es llamada implícitamente por using
para cargar paquetes.
Al buscar archivos, require
primero busca código de paquete en el arreglo global LOAD_PATH
. require
es sensible a mayúsculas y minúsculas en todas las plataformas, incluidas aquellas con sistemas de archivos que no distinguen entre mayúsculas y minúsculas, como macOS y Windows.
Para más detalles sobre la carga de código, consulta las secciones del manual sobre módulos y computación paralela.
Base.compilecache
— FunctionBase.compilecache(module::PkgId)
Crea un archivo de caché precompilado para un módulo y todas sus dependencias. Esto se puede usar para reducir los tiempos de carga de paquetes. Los archivos de caché se almacenan en DEPOT_PATH[1]/compiled
. Consulta Module initialization and precompilation para notas importantes.
Base.isprecompiled
— FunctionBase.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)
Devuelve si un PkgId dado dentro del proyecto activo está precompilado.
Por defecto, esta verificación observa el mismo enfoque que la carga de código con respecto a cuándo se cargan diferentes versiones de las dependencias en comparación con lo que se espera. Para ignorar los módulos cargados y responder como si estuvieras en una nueva sesión de julia, especifica ignore_loaded=true
.
Esta función requiere al menos Julia 1.10.
Base.get_extension
— Functionget_extension(parent::Module, extension::Symbol)
Devuelve el módulo para extension
de parent
o devuelve nothing
si la extensión no está cargada.
Internals
Base.GC.gc
— FunctionGC.gc([full=true])
Realiza la recolección de basura. El argumento full
determina el tipo de recolección: una recolección completa (por defecto) recorre todos los objetos vivos (es decir, marca completa) y debería recuperar memoria de todos los objetos inalcanzables. Una recolección incremental solo recupera memoria de objetos jóvenes que no son alcanzables.
El GC puede decidir realizar una recolección completa incluso si se solicitó una recolección incremental.
El uso excesivo probablemente conducirá a un rendimiento deficiente.
Base.GC.enable
— FunctionGC.enable(on::Bool)
Controla si la recolección de basura está habilitada utilizando un argumento booleano (true
para habilitado, false
para deshabilitado). Devuelve el estado anterior de la recolección de basura.
Deshabilitar la recolección de basura debe usarse solo con precaución, ya que puede hacer que el uso de memoria crezca sin límites.
Base.GC.@preserve
— MacroGC.@preserve x1 x2 ... xn expr
Marca los objetos x1, x2, ...
como en uso durante la evaluación de la expresión expr
. Esto solo es necesario en código inseguro donde expr
utiliza implícitamente memoria u otros recursos propiedad de uno de los x
.
Uso implícito de x
cubre cualquier uso indirecto de recursos lógicamente propiedad de x
que el compilador no puede ver. Algunos ejemplos:
- Acceder a la memoria de un objeto directamente a través de un
Ptr
- Pasar un puntero a
x
accall
- Usar recursos de
x
que serían limpiados en el finalizador.
@preserve
generalmente no debería tener ningún impacto en el rendimiento en casos de uso típicos donde extiende brevemente la vida del objeto. En la implementación, @preserve
tiene efectos como proteger objetos asignados dinámicamente de la recolección de basura.
Ejemplos
Al cargar desde un puntero con unsafe_load
, el objeto subyacente se utiliza implícitamente, por ejemplo, x
se utiliza implícitamente por unsafe_load(p)
en lo siguiente:
julia> let
x = Ref{Int}(101)
p = Base.unsafe_convert(Ptr{Int}, x)
GC.@preserve x unsafe_load(p)
end
101
Al pasar punteros a ccall
, el objeto apuntado se utiliza implícitamente y debe ser preservado. (Sin embargo, ten en cuenta que normalmente deberías pasar x
directamente a ccall
, lo cual cuenta como un uso explícito.)
julia> let
x = "Hello"
p = pointer(x)
Int(GC.@preserve x @ccall strlen(p::Cstring)::Csize_t)
# Alternativa preferida
Int(@ccall strlen(x::Cstring)::Csize_t)
end
5
Base.GC.safepoint
— FunctionGC.safepoint()
Inserta un punto en el programa donde puede ejecutarse la recolección de basura. Esto puede ser útil en casos raros en programas multihilo donde algunos hilos están asignando memoria (y por lo tanto pueden necesitar ejecutar GC) pero otros hilos están realizando solo operaciones simples (sin asignación, cambios de tarea o E/S). Llamar a esta función periódicamente en hilos que no asignan permite que la recolección de basura se ejecute.
Esta función está disponible a partir de Julia 1.4.
Base.GC.enable_logging
— FunctionGC.enable_logging(on::Bool)
Cuando está activado, imprime estadísticas sobre cada GC en stderr.
Base.GC.logging_enabled
— FunctionGC.logging_enabled()
Devuelve si el registro de GC ha sido habilitado a través de GC.enable_logging
.
Base.Meta.lower
— Functionlower(m, x)
Toma la expresión x
y devuelve una expresión equivalente en forma reducida para ejecutar en el módulo m
. Ver también code_lowered
.
Base.Meta.@lower
— Macro@lower [m] x
Devuelve la forma reducida de la expresión x
en el módulo m
. Por defecto, m
es el módulo en el que se llama a la macro. Ver también lower
.
Base.Meta.parse
— Methodparse(str, start; greedy=true, raise=true, depwarn=true, filename="none")
Analiza la cadena de expresión y devuelve una expresión (que podría ser pasada a eval para su ejecución). start
es el índice de unidad de código en str
del primer carácter desde el cual comenzar a analizar (como con todos los índices de cadena, estos no son índices de caracteres). Si greedy
es true
(por defecto), parse
intentará consumir la mayor cantidad de entrada posible; de lo contrario, se detendrá tan pronto como haya analizado una expresión válida. Las expresiones incompletas pero de otro modo sintácticamente válidas devolverán Expr(:incomplete, "(mensaje de error)")
. Si raise
es true
(por defecto), los errores de sintaxis que no sean expresiones incompletas generarán un error. Si raise
es false
, parse
devolverá una expresión que generará un error al ser evaluada. Si depwarn
es false
, se suprimirán las advertencias de deprecación. El argumento filename
se utiliza para mostrar diagnósticos cuando se genera un error.
julia> Meta.parse("(α, β) = 3, 5", 1) # inicio de la cadena
(:((α, β) = (3, 5)), 16)
julia> Meta.parse("(α, β) = 3, 5", 1, greedy=false)
(:((α, β)), 9)
julia> Meta.parse("(α, β) = 3, 5", 16) # final de la cadena
(nothing, 16)
julia> Meta.parse("(α, β) = 3, 5", 11) # índice de 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")
Analiza la cadena de expresión de manera codiciosa, devolviendo una única expresión. Se lanza un error si hay caracteres adicionales después de la primera expresión. Si raise
es true
(por defecto), los errores de sintaxis generarán un error; de lo contrario, parse
devolverá una expresión que generará un error al evaluarse. Si depwarn
es false
, se suprimirán las advertencias de deprecación. El argumento filename
se utiliza para mostrar diagnósticos cuando se lanza un error.
julia> Meta.parse("x = 3")
:(x = 3)
julia> Meta.parse("1.0.2")
ERROR: ParseError:
# Error @ none:1:1
1.0.2
└──┘ ── constante numérica inválida
[...]
julia> Meta.parse("1.0.2"; raise = false)
:($(Expr(:error, "constante numérica inválida "1.0."")))
julia> Meta.parse("x = ")
:($(Expr(:incomplete, "incompleto: fin prematuro de la entrada")))
Base.Meta.ParseError
— TypeParseError(msg)
La expresión pasada a la función parse
no pudo ser interpretada como una expresión válida de Julia.
Core.QuoteNode
— TypeQuoteNode
Un fragmento de código citado, que no soporta interpolación. Consulta la sección del manual sobre QuoteNodes para más detalles.
Base.macroexpand
— Functionmacroexpand(m::Module, x; recursive=true)
Toma la expresión x
y devuelve una expresión equivalente con todas las macros eliminadas (expandidas) para ejecutarse en el módulo m
. La palabra clave recursive
controla si también se expanden niveles más profundos de macros anidadas. Esto se demuestra en el ejemplo a continuación:
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
Devuelve la expresión equivalente con todas las macros eliminadas (expandidas). Si se proporcionan dos argumentos, el primero es el módulo en el que se evalúa.
Hay diferencias entre @macroexpand
y macroexpand
.
- Mientras que
macroexpand
toma un argumento de palabra claverecursive
,@macroexpand
es siempre recursivo. Para una versión de macro no recursiva, consulte@macroexpand1
. - Mientras que
macroexpand
tiene un argumentomodule
explícito,@macroexpand
siempre expande con respecto al módulo en el que se llama.
Esto se ve mejor en el siguiente ejemplo:
julia> module M
macro m()
1
end
function f()
(@macroexpand(@m),
macroexpand(M, :(@m)),
macroexpand(Main, :(@m))
)
end
end
M
julia> macro m()
2
end
@m (macro with 1 method)
julia> M.f()
(1, 1, 2)
Con @macroexpand
la expresión se expande donde aparece @macroexpand
en el código (módulo M
en el ejemplo). Con macroexpand
la expresión se expande en el módulo dado como primer argumento.
La forma de dos argumentos requiere al menos Julia 1.11.
Base.@macroexpand1
— Macro@macroexpand1 [mod,] ex
Versión no recursiva de @macroexpand
.
Base.code_lowered
— Functioncode_lowered(f, types; generated=true, debuginfo=:default)
Devuelve un array de las formas reducidas (IR) para los métodos que coinciden con la función genérica dada y la firma de tipo.
Si generated
es false
, las instancias de CodeInfo
devueltas corresponderán a implementaciones de respaldo. Se lanzará un error si no existe ninguna implementación de respaldo. Si generated
es true
, estas instancias de CodeInfo
corresponderán a los cuerpos de método generados al expandir los generadores.
La palabra clave debuginfo
controla la cantidad de metadatos de código presentes en la salida.
Ten en cuenta que se lanzará un error si types
no son tipos hoja cuando generated
es true
y cualquiera de los métodos correspondientes es un método @generated
.
Base.code_typed
— Functioncode_typed(f, types; kw...)
Devuelve un array de la forma reducida inferida por tipo (IR) para los métodos que coinciden con la función genérica dada y la firma de tipo.
Argumentos de Palabra Clave
optimize::Bool = true
: opcional, controla si se aplican optimizaciones adicionales, como la inserción en línea.debuginfo::Symbol = :default
: opcional, controla la cantidad de metadatos de código presentes en la salida, las opciones posibles son:source
o:none
.
Argumentos Internos de Palabra Clave
Esta sección debe considerarse interna y es solo para quienes entienden los internals del compilador de Julia.
world::UInt = Base.get_world_counter()
: opcional, controla la edad del mundo a utilizar al buscar métodos, usa la edad del mundo actual si no se especifica.interp::Core.Compiler.AbstractInterpreter = Core.Compiler.NativeInterpreter(world)
: opcional, controla el intérprete abstracto a utilizar, usa el intérprete nativo si no se especifica.
Ejemplos
Se pueden poner los tipos de argumento en una tupla para obtener el correspondiente 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
— Functionprecompilar(f, argtypes::Tuple{Vararg{Any}})
Compila la función dada f
para la tupla de argumentos (de tipos) argtypes
, pero no la ejecuta.
precompile(f, argtypes::Tuple{Vararg{Any}}, m::Method)
Precompilar un método específico para los tipos de argumento dados. Esto puede usarse para precompilar un método diferente al que normalmente sería elegido por el despacho, imitando así invoke
.
Base.jit_total_bytes
— FunctionBase.jit_total_bytes()
Devuelve la cantidad total (en bytes) asignada por el compilador just-in-time para, por ejemplo, código nativo y datos.
Meta
Base.Meta.quot
— FunctionMeta.quot(ex)::Expr
Cita la expresión ex
para producir una expresión con cabeza quote
. Esto se puede usar, por ejemplo, para representar objetos del tipo Expr
en el AST. Consulta también la sección del manual sobre QuoteNode.
Ejemplos
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
Devuelve true
si ex
es un Expr
con el tipo dado head
y opcionalmente que la lista de argumentos tiene una longitud de n
. head
puede ser un Symbol
o una colección de Symbol
s. Por ejemplo, para verificar que a una macro se le pasó una expresión de llamada a función, podrías usar isexpr(ex, :call)
.
Ejemplos
julia> ex = :(f(x))
:(f(x))
julia> Meta.isexpr(ex, :block)
false
julia> Meta.isexpr(ex, :call)
true
julia> Meta.isexpr(ex, [:block, :call]) # múltiples cabezas posibles
true
julia> Meta.isexpr(ex, :call, 1)
false
julia> Meta.isexpr(ex, :call, 2)
true
Base.isidentifier
— Function isidentifier(s) -> Bool
Devuelve si el símbolo o cadena s
contiene caracteres que se interpretan como un identificador ordinario válido (no un operador binario/unario) en el código de Julia; véase también Base.isoperator
.
Internamente, Julia permite cualquier secuencia de caracteres en un Symbol
(excepto \0
s), y las macros utilizan automáticamente nombres de variables que contienen #
para evitar colisiones de nombres con el código circundante. Para que el analizador reconozca una variable, utiliza un conjunto limitado de caracteres (ampliamente extendido por Unicode). isidentifier()
hace posible consultar directamente al analizador si un símbolo contiene caracteres válidos.
Ejemplos
julia> Meta.isidentifier(:x), Meta.isidentifier("1x")
(true, false)
Base.isoperator
— Functionisoperator(s::Symbol)
Devuelve true
si el símbolo puede ser utilizado como un operador, false
en caso contrario.
Ejemplos
julia> Meta.isoperator(:+), Meta.isoperator(:f)
(true, false)
Base.isunaryoperator
— Functionisunaryoperator(s::Symbol)
Devuelve true
si el símbolo puede ser utilizado como un operador unario (prefijo), false
en caso contrario.
Ejemplos
julia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f)
(true, true, false)
Base.isbinaryoperator
— Functionisbinaryoperator(s::Symbol)
Devuelve true
si el símbolo puede ser utilizado como un operador binario (infixo), false
en caso contrario.
Ejemplos
julia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f)
(true, false, false)
Base.Meta.show_sexpr
— FunctionMeta.show_sexpr([io::IO,], ex)
Muestra la expresión ex
como una S-expresión al estilo lisp.
Ejemplos
julia> Meta.show_sexpr(:(f(x, g(y,z))))
(:call, :f, :x, (:call, :g, :y, :z))