我的假设是否正确,Ruby在字符串插值期间解释对象时不会调用to_s
或方法?to_str
String
a = "Hallo"
class String
def to_s
"Servus"
end
end
def a.to_s
"Servus"
end
puts "Hier sagt man #{a}"
=> 在这里说 你好
检查一个对象是否String
比简单地调用该to_s
方法更有效率?
我的假设是否正确,Ruby在字符串插值期间解释对象时不会调用to_s
或方法?to_str
String
a = "Hallo"
class String
def to_s
"Servus"
end
end
def a.to_s
"Servus"
end
puts "Hier sagt man #{a}"
=> 在这里说 你好
检查一个对象是否String
比简单地调用该to_s
方法更有效率?
这是正确的。
您提供的测试并未排除解析器通过识别分配给字符串文字而采取捷径的可能性
a
。以下测试确实如此:现在,Ruby 实际上不执行
a
任何类型的“局部变量是文字字符串”自动替换,因为 Ruby 非常动态,以至于可以在解析器不知情的情况下在以下任何一行代码中更新的值。但如果您还不确定情况是否如此,那么像上面这样的测试可以保证这一点。下面是另一个有趣的测试,它表明 Ruby(至少是 C Ruby)没有使用一些秘密的快捷方式来检查它是否正好是
String
,而是使用更类似于is_a?
:如果我们看到了
a: foo
,我们就会知道使用了一个非常简单(并且可能更有效)的检查,并且无法识别该Foo
对象是子类的实例String
。鉴于上述情况,我们排除了该测试
String
是针对类进行优化的简单测试的可能性String
。无需检查每个 Ruby 实现中的代码,我们还可以确定其他几件事:is_a?
方法调用即可识别对象是否是String
子类的实例。is_a?
,因为它可以用于rb_obj_is_kind_of
任何对象类型。to_s
并to_str
涉及至少 1 或 2 个方法查找。实际调用它们涉及未知数量的方法查找和其他调用。to_s
或to_str
实际返回字符串,因此is_a?
必须重复检查。考虑到这些因素,我们可以说,检查对象是否为要调用的 as或不先检查至少要高效两倍,而且平均而言,它可能高效得多。
String
to_s
to_str