假设我有一个来自SQL查询的传入值,如下所示:
grok = Foo.select(:foo_attr1, :foo_attr2).first
Run Code Online (Sandbox Code Playgroud)
foo_attr2是一个可以为空的领域.现在假设我需要对输出进行处理(如果存在的话).
krug = grok.foo_attr2.try(:bar).try(:baz)
gnar = grok.foo_attr2 && grok.foo_attr2.bar.baz # Assumes bar will always return output that can be baz'd
Run Code Online (Sandbox Code Playgroud)
这两个操作中哪一个更好用,为什么?
使用gnar = grok.foo_attr2 && grok.foo_attr2.bar.bazRuby的逻辑运算符完成后肯定会更快.虽然try是由Rails引入并进行额外的if-else条件检查.来自代码:
# File activesupport/lib/active_support/core_ext/object/try.rb, line 41
def try(*a, &b)
if a.empty? && block_given?
yield self
else
public_send(*a, &b) if respond_to?(a.first)
end
end
Run Code Online (Sandbox Code Playgroud)
好吧,这是一个基准,以准确显示我想说的内容:
class Object
def try(*a, &b)
if a.empty? && block_given?
yield self
else
public_send(*a, &b) if respond_to?(a.first)
end
end
end
class Foo
attr_reader :a
def initialize(a = nil)
@a = a
end
end
require "benchmark"
bar = Foo.new
baz = Foo.new(1)
n = 10000000
Benchmark.bm(40) do |x|
x.report("try"){ n.times { bar.a.try(:class).try(:to_s) } }
x.report("&& "){ n.times { baz.a && baz.a.class.to_s } }
end
Run Code Online (Sandbox Code Playgroud)
结果是:
user system total real
try 10.800000 0.030000 10.830000 ( 10.829770)
&& 3.940000 0.010000 3.950000 ( 3.944375)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1029 次 |
| 最近记录: |