我知道我可以使用class作为Hash键,但这是一个好习惯吗?在性能或测试方面有任何缺点吗?
{
SomeClassA: 'hash value',
AnotherClass: 'hash value'
}
答案 0 :(得分:6)
{
SomeClassA: 'hash value',
AnotherClass: 'hash value'
}
实际上相当于:
{
:SomeClassA => 'hash value',
:AnotherClass => 'hash value'
}
键是符号。在" new"文字哈希语法键只被视为文字,它们被转换为符号(假设它们是有效的语法)。
要使用常量,范围或任何其他类型的对象,您可以将其作为使用hashrockets所需的键:
{
SomeClassA => 'hash value',
AnotherClass => 'hash value'
}
这是一个好习惯吗?
这种技术可以在少数有限的情况下使用。例如,替换一系列if
语句。
def foo(bar)
if bar.is_a? SomeClassA
'hash value'
end
if bar.is_a? AnotherClass
'another value'
end
end
def foo(bar)
{
SomeClassA => 'hash value',
AnotherClass => 'another value'
}[bar]
end
但我宁愿在那里使用案例陈述,因为它的意图更清晰,更灵活。
在性能或测试方面是否有任何缺点?
您创建的每个哈希都会有一些键指向内存中完全相同的对象,就像您使用符号一样。
一个很大的问题是Rails猴子补丁const_missing
自动加载文件 - 当你引用类名时,rails会将文件从文件系统加载到内存中。这就是您声明关联的原因:
class Foo < ApplicationRecord
belongs_to :bar, class_name: "Baz"
end
它允许Rails在需要时延迟加载Baz。您可以通过以下示例执行相同的操作:
def foo(bar)
{
'SomeClassA' => 'hash value',
'AnotherClass' => 'another value'
}[bar.name]
end
答案 1 :(得分:3)
该哈希使用符号而不是类作为键,但您可以通过
使用Classhash = { SomeClassA => "some value" }
我无法想到为什么它会比使用任何其他对象更糟糕,因为
Ruby中的类是第一类对象---每个对象都是类
的实例Class
所以
{ SomeClassA => "some value" }
在功能上等同于
{ "Some String" => "some value" }
答案 2 :(得分:2)
你所拥有的不是课堂钥匙而是符号。 尝试
class A
end
class B
end
hash = {A: "Some", B: "Code"}
hash.keys[0].class
=> Symbol
但仍A.class
=&gt; Class
如果是符号效果,POST很棒
您也可以查看有关user-defined class as hash keys
的ruby文档答案 3 :(得分:0)
虽然你可以做到,但我想不出使用它的原因。使用符号或字符串作为键更有效,因为程序不必加载整个类。 (旁注,正如其他人指出的那样,你的例子实际上是使用符号键,你需要使用哈希火箭来使用类名作为键)