我知道可以将类作为哈希键,但这是一个好的实践吗?在性能或测试方面有什么缺点吗?
{
SomeClassA: 'hash value',
AnotherClass: 'hash value'
}
我知道可以将类作为哈希键,但这是一个好的实践吗?在性能或测试方面有什么缺点吗?
{
SomeClassA: 'hash value',
AnotherClass: 'hash value'
}
{
SomeClassA: 'hash value',
AnotherClass: 'hash value'
}
{
:SomeClassA => 'hash value',
:AnotherClass => 'hash value'
}
键是符号。在“新”的字面哈希语法中,键只被视为文字,它们会被转换为符号(前提是它们是有效的语法)。
如果要使用常量、范围或任何其他类型的对象作为键,则需要使用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
但是,我更愿意在这里使用 case 语句,因为这样更清晰明了,而且更灵活。
从性能或测试角度来看,是否存在任何缺点?
你创建的每个哈希都会有指向内存中完全相同对象的键,就像使用符号一样。
Rails 的一个大陷阱是将 const_missing
修改为自动加载文件 - 当引用一个类名时,Rails 将从文件系统加载文件到内存中。这就是为什么要使用以下方式声明关联:
class Foo < ApplicationRecord
belongs_to :bar, class_name: "Baz"
end
def foo(bar)
{
'SomeClassA' => 'hash value',
'AnotherClass' => 'another value'
}[bar.name]
end
{ 0_foo: 2 }
。 - max:0_foo
是无效的。你必须使用 :'0_foo'
或 { '0_foo': 2 }
。 - Stefan这个哈希表使用符号作为键而不是类,但你可以通过以下方式使用类(Class):
hash = { SomeClassA => "some value" }
我想不出为什么使用它会比使用其他对象更糟糕,因为
Ruby中的类是一级对象——每个类都是
Class
类的实例。
所以
{ SomeClassA => "some value" }
是功能上等同于
{ "Some String" => "some value" }
class A
end
class B
end
hash = {A: "Some", B: "Code"}
hash.keys[0].class
=> Symbol
但是仍然 A.class
=> Class
关于符号性能,这篇文章非常棒
此外,您可以查看有关将用户定义的类用作哈希键的 Ruby 文档。
虽然你可以这样做,但我想不出使用它的理由。使用符号或字符串作为键更加高效,因为程序不必加载整个类。(顺便提一下,正如其他人指出的那样,你的示例实际上正在使用符号键,如果要使用类名作为键,则需要使用哈希箭头)