自定义使用类似NamedTuple的括号

huangapple go评论57阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年6月1日 09:21:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76378134.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定