有没有办法在 Crystal 中使用带有 splat 运算符的非 Tuple 对象?
Is there a way to use non Tuple objects with splat operator in Crystal?
是否有一些函数或语法结构可以使下一个示例正常工作?
使用 Array
参数调用 Hash#values_at
函数:
h = {"a" => 1, "b" => 2, "c" => 3}
ary = ["a", "b"]
h.values_at(*ary) # Error: argument to splat must be a tuple, not Array(String)
传递Hash
初始化class或struct:
struct Point
def initialize(@x : Int32, @y : Int32)
end
end
h = {"x" => 1, "y" => 2}
Point.new(**h) # Error: argument to double splat must be a named tuple, not Hash(String, Int32)
Array 和 Hash 是动态扩展的容器,元素的数量可能会在运行时发生变化,当您尝试展开时,数组可能为空。
Tuple 和 NamedTuple 由固定数量的元素组成,这些元素在编译时是已知的,因此它们可用于 splats。如果你的数据容器的格式没有改变,你可以直接使用 Tuple 和 NamedTuple。
ary = {"a", "b"}
h.values_at(*ary)
第一个例子可能是不可能的,这取决于具体情况。但是如果元素的长度是固定的,你可以这样做:
h = {"a" => 1, "b" => 2, "c" => 3}
ary = ["a", "b"]
p h.values_at(*{String, String}.from(ary))
https://carc.in/#/r/3oot See Tuple.from
NamedTuple
支持相同的方法:
struct Point
def initialize(@x : Int32, @y : Int32)
end
end
h = {"x" => 1, "y" => 2}
p Point.new(**{x: Int32, y: Int32}.from(h))
https://carc.in/#/r/3oov See NamedTuple.from
这两个只是确保类型和在运行时手动分解结构的一些糖分,主要在数据来自外部源时有用,例如从 JSON.
解析
当然,在可能的情况下,首先创建和使用 Tuple
而不是 Array
和 NamedTuple
而不是 Hash
。
是否有一些函数或语法结构可以使下一个示例正常工作?
使用 Array
参数调用 Hash#values_at
函数:
h = {"a" => 1, "b" => 2, "c" => 3}
ary = ["a", "b"]
h.values_at(*ary) # Error: argument to splat must be a tuple, not Array(String)
传递Hash
初始化class或struct:
struct Point
def initialize(@x : Int32, @y : Int32)
end
end
h = {"x" => 1, "y" => 2}
Point.new(**h) # Error: argument to double splat must be a named tuple, not Hash(String, Int32)
Array 和 Hash 是动态扩展的容器,元素的数量可能会在运行时发生变化,当您尝试展开时,数组可能为空。
Tuple 和 NamedTuple 由固定数量的元素组成,这些元素在编译时是已知的,因此它们可用于 splats。如果你的数据容器的格式没有改变,你可以直接使用 Tuple 和 NamedTuple。
ary = {"a", "b"}
h.values_at(*ary)
第一个例子可能是不可能的,这取决于具体情况。但是如果元素的长度是固定的,你可以这样做:
h = {"a" => 1, "b" => 2, "c" => 3}
ary = ["a", "b"]
p h.values_at(*{String, String}.from(ary))
https://carc.in/#/r/3oot See Tuple.from
NamedTuple
支持相同的方法:
struct Point
def initialize(@x : Int32, @y : Int32)
end
end
h = {"x" => 1, "y" => 2}
p Point.new(**{x: Int32, y: Int32}.from(h))
https://carc.in/#/r/3oov See NamedTuple.from
这两个只是确保类型和在运行时手动分解结构的一些糖分,主要在数据来自外部源时有用,例如从 JSON.
解析当然,在可能的情况下,首先创建和使用 Tuple
而不是 Array
和 NamedTuple
而不是 Hash
。