Julia tem duas sintaxes para construir tuplas nomeadas.
A primeira sintaxe usa pares de chaves e valores dentro de parênteses, sem ponto e vírgula.
named_tuple = (a=1, b=2, c=3)
A segunda forma da sintaxe usa um ponto e vírgula inicial.
named_tuple = (; a=1, b=2, c=3)
Pelo que posso perceber pela documentação, ambos os formulários produzem o mesmo resultado. (Um NamedTuple
objeto.)
Não parece haver nenhuma diferença entre os dois formulários a seguir.
julia> tuple1 = (a=1, b=2, c=3)
(a = 1, b = 2, c = 3)
julia> typeof(tuple1)
@NamedTuple{a::Int64, b::Int64, c::Int64}
julia> tuple2 = (; a=1, b=2, c=3)
(a = 1, b = 2, c = 3)
julia> typeof(tuple2)
@NamedTuple{a::Int64, b::Int64, c::Int64}
Parece ser possível criar um NamedTuple
a partir de uma série de pares, mas somente se o ponto e vírgula for incluído.
Em outras palavras, essa sintaxe é válida e produz o resultado esperado
julia> tuple3 = (; :a=>1, :b=>2, :c=>3)
(a = 1, b = 2, c = 3)
julia> typeof(tuple3)
@NamedTuple{a::Int64, b::Int64, c::Int64}
por outro lado, o seguinte não
julia> tuple4 = (:a=>1, :b=>2, :c=>3)
(:a => 1, :b => 2, :c => 3)
julia> typeof(tuple4)
Tuple{Pair{Symbol, Int64}, Pair{Symbol, Int64}, Pair{Symbol, Int64}}
Isso produz um Tuple
de Pair
em vez de um NamedTuple
.
Qual é a finalidade de cada formulário ou o motivo de ter dois formulários diferentes?
A sintaxe
(a=1, ...)
e(; a=1, ...)
são basicamente as mesmas: ambas são construtoras de tuplas nomeadas. Uma diferença é que a segunda forma permite que você omita a vírgula e ainda tenha uma tupla nomeada, enquanto(a=1)
é uma expressão de atribuição. Além disso, é claro que()
é uma tupla vazia e(;)
é uma tupla nomeada vazia.A segunda forma, com pares, se conecta à lógica de argumentos de palavras-chave de Julia, que diz que
f(args; :a=>1, :b=>2)
passa argumentos de palavras-chavea=1
eb=2
paraf
. (Isso é útil principalmente quando você tem um iterador de pares símbolo-valor, como um Dict, e quersplat...
transformá-lo em palavras-chave.)