没有将 Struct 隐式转换为 Array
No implicit conversion of Struct into Array
我遇到了一个问题,我正在处理一个结构数组并想 transpose
它们,但遇到了一个错误:
TypeError (no implicit conversion of Struct into Array)
我认为(错误地)这种隐式转换只是在每个对象上调用 to_a
(如果可用),尽管结构确实有一个 to_a
method.
所以我的问题分为两部分:
- 如果可以,我该如何实现这种隐式转换?
- 其次,为什么会这样?为什么结构体不能隐式转换为数组,却可以显式转换?
这是一个产生错误的最小示例:
S = Struct.new(:a, :b)
a = S.new(1, 2)
# => #<struct S a=1, b=2>
b = S.new(3, 4)
# => #<struct S a=3, b=4>
[a, b].transpose
# TypeError (no implicit conversion of S into Array)
[a, b].map(&:to_a)
# => [[1, 2], [3, 4]]
# Therefore, the extra step I'd have to take to transpose:
[a, b].map(&:to_a).transpose
# => [[1, 3], [2, 4]]
在此先感谢您的帮助。
我在研究这个问题时实际上已经找到了这个问题的答案,所以将弹出答案,因为我之前搜索时找不到任何类似的东西。
Ruby 使用不同的强制方法进行显式与隐式转换:
| Explicit | Implicit |
|----------|----------|
| to_i | to_int |
| to_s | to_str |
| to_a | to_ary |
| to_h | to_hash |
|----------|----------|
所以这里的问题是结构没有 to_ary
方法:
a.to_ary
# NoMethodError (undefined method `to_ary' for #<struct S a=1, b=2>)
因此,如果我们在有问题的结构上定义这个方法,我们可以隐式转换:
S.define_method(:to_ary) do
self.to_a
end
[a, b].transpose
# => [[1, 3], [2, 4]]
瞧:)
if I can, how do I implement this implicit conversion?
您可以将块传递给 Struct.new
,然后在那里定义您的方法:
S = Struct.new(:a, :b) do
alias_method :to_ary, :to_a
end
secondly, why is this the case? Why can't structs be implicitly converted to arrays, yet can be explicitly converted?
这有点哲理,但是to_ary
、to_int
等表示那些对象真的分别表示数组、整数等;他们只是不完全正确的类型。
to_a
、to_i
的单字母变体不同,表示对象可能属于数组、整数等,但它们的底层结构完全不同,或者仅代表其真实语义的一部分。
我遇到了一个问题,我正在处理一个结构数组并想 transpose
它们,但遇到了一个错误:
TypeError (no implicit conversion of Struct into Array)
我认为(错误地)这种隐式转换只是在每个对象上调用 to_a
(如果可用),尽管结构确实有一个 to_a
method.
所以我的问题分为两部分:
- 如果可以,我该如何实现这种隐式转换?
- 其次,为什么会这样?为什么结构体不能隐式转换为数组,却可以显式转换?
这是一个产生错误的最小示例:
S = Struct.new(:a, :b)
a = S.new(1, 2)
# => #<struct S a=1, b=2>
b = S.new(3, 4)
# => #<struct S a=3, b=4>
[a, b].transpose
# TypeError (no implicit conversion of S into Array)
[a, b].map(&:to_a)
# => [[1, 2], [3, 4]]
# Therefore, the extra step I'd have to take to transpose:
[a, b].map(&:to_a).transpose
# => [[1, 3], [2, 4]]
在此先感谢您的帮助。
我在研究这个问题时实际上已经找到了这个问题的答案,所以将弹出答案,因为我之前搜索时找不到任何类似的东西。
Ruby 使用不同的强制方法进行显式与隐式转换:
| Explicit | Implicit |
|----------|----------|
| to_i | to_int |
| to_s | to_str |
| to_a | to_ary |
| to_h | to_hash |
|----------|----------|
所以这里的问题是结构没有 to_ary
方法:
a.to_ary
# NoMethodError (undefined method `to_ary' for #<struct S a=1, b=2>)
因此,如果我们在有问题的结构上定义这个方法,我们可以隐式转换:
S.define_method(:to_ary) do
self.to_a
end
[a, b].transpose
# => [[1, 3], [2, 4]]
瞧:)
if I can, how do I implement this implicit conversion?
您可以将块传递给 Struct.new
,然后在那里定义您的方法:
S = Struct.new(:a, :b) do
alias_method :to_ary, :to_a
end
secondly, why is this the case? Why can't structs be implicitly converted to arrays, yet can be explicitly converted?
这有点哲理,但是to_ary
、to_int
等表示那些对象真的分别表示数组、整数等;他们只是不完全正确的类型。
to_a
、to_i
的单字母变体不同,表示对象可能属于数组、整数等,但它们的底层结构完全不同,或者仅代表其真实语义的一部分。