英文:
Custom use of brackets like NamedTuple
问题
以下是翻译好的部分:
- Does the creation of a NamedTuple rely on macros/metaprogramming?(创建NamedTuple是否依赖于宏/元编程?)
- What does
:splatnew
do?(:splatnew
是做什么的?) - How would you approach making your own custom use of brackets?(你如何处理创建自己的自定义括号用法?)
英文:
Brackets in Julia are used for Parametric Types as far as I encountered by now.
There is however one example of curly brackets being used in a different way:
NamedTuple{(:a, :b)}((1, 2))
This constructs the NamedTuple (a=1, b=2)
, but you pass the field names in brackets.
The source code for the NamedTuple is a bit obscure in my opinion.
NamedTuple() = NamedTuple{(),Tuple{}}(())
NamedTuple{names}(args::Tuple) where {names} = NamedTuple{names,typeof(args)}(args)
eval(Core, :(NamedTuple{names,T}(args::T) where {names, T <: Tuple} =
$(Expr(:splatnew, :(NamedTuple{names,T}), :args))))
- Does the creation of a NamedTuple rely on macros/metaprogramming?
- What does
:splatnew
do? - How would you approach making your own custom use of brackets?
答案1
得分: 3
但是有一个例子是花括号以不同的方式使用的:
它们以相同的方式使用。字段名称是 NamedTuple
的参数。要查看这一点,请检查:
julia> typeof((a=1, b=2))
NamedTuple{(:a, :b), Tuple{Int64, Int64}}
唯一的问题是你省略了传递第二个参数,这种情况下是 Tuple{Int64, Int64}
,但在这种情况下,Julia 允许省略传递所有参数。你可以省略它们的原因在你引用的这段代码中处理:
NamedTuple{names}(args::Tuple) where {names} = NamedTuple{names,typeof(args)}(args)
这将参数扩展为包括元组作为第二个参数。
创建 NamedTuple 是否依赖于宏/元编程?
是的,这段代码:
eval(Core, :(NamedTuple{names,T}(args::T) where {names, T <: Tuple} =
$(Expr(:splatnew, :(NamedTuple{names,T}), :args))))
在 Core
模块中评估表达式。这是元编程(但不是宏)。
:splatnew
是什么作用?
正如你可以在 Julia 手册 中阅读的那样,它是:
类似于
new
,但字段值作为单个元组传递。如果new
是一个一流函数,那么它的工作方式类似于splat(new)
,因此得名。
所以它本质上是 new
,但接受一个位置参数,该参数会被展开。
如何制定自己的括号的自定义用法?
这不是括号的自定义用法。语义遵循标准的参数化类型规则。
英文:
> There is however one example of curly brackets being used in a different way:
They are used in the same way. Field names are parameters of a NamedTuple
. To see this check:
julia> typeof((a=1, b=2))
NamedTuple{(:a, :b), Tuple{Int64, Int64}}
The only issue is that you are omitting passing the second parameter, which is Tuple{Int64, Int64}
in this case but Julia allows omitting passing all parameters in this case. The reason why you can omit them is handled in this code you quoted:
NamedTuple{names}(args::Tuple) where {names} = NamedTuple{names,typeof(args)}(args)
which expands the parameters to include the tuple as a second parameter.
> Does the creation of a NamedTuple rely on macros/metaprogramming?
Yes, the code:
eval(Core, :(NamedTuple{names,T}(args::T) where {names, T <: Tuple} =
$(Expr(:splatnew, :(NamedTuple{names,T}), :args))))
evaluates the expression in Core
module. This is metaprogamming (but not macro).
> What does :splatnew
do?
As you can read in Julia Manual it is:
> Similar to new
, except field values are passed as a single tuple. Works similarly to splat(new)
if new were a first-class function, hence the name.
So essentially it is new
but accepting one positional argument that is a tuple that gets splatted.
> How would you approach making your own custom use of brackets?
This is not a custom use of brackets. The semantics follows standard parametric type rules.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论