两个等于运营商的情况如何?

时间:2013-12-30 19:41:10

标签: ruby

我正在考虑这个安排:

if trie.nil?
  trie = @hash[letter] = Trie.new(@level + 1)
end

并从右边开始解释它,如:

  1. 使用适当的参数从Trie类创建一个新实例。
  2. 该实例成为@hash哈希中的值,并由letter密钥编制索引。
  3. 该实例也存储在变量trie中,因此可以在别处使用。
  4. 我有多接近? Trie表的实例是否真的存储在哈希中?

4 个答案:

答案 0 :(得分:2)

问题是逻辑不清楚。在一行上使用两个分配是等待中的维护问题。

相反,用两行代码编写代码会更清晰,更具惯用性:

trie = Trie.new(@level + 1) if trie.nil?
@hash[letter] = trie

或:

trie ||= Trie.new(@level + 1)
@hash[letter] = trie

第二个示例使用||=检查trie是否已初始化,即不是nil。如果它不是零,代码就会失效。如果 为nil,那么将为trie分配新Trie实例的值。并且,在所有情况下,@hash[letter]都会被分配当前值trie

这是一个很好的例子,当有人试图在代码中成为男子气概时会发生什么。 他们了解他们正在做什么,但他们让其他人都摸不着头脑,想知道两件事:

  • 那是做什么的?!
  • 为什么他们这样做??

在代码审查中,听起来都不是一件好事,所以写下你的代码就好像其他人会在未来的路上阅读它一样,因为,某些人的意愿很好 - 无论是你,还是谁能维护你的代码 - 所以要善待。

答案 1 :(得分:1)

您的解释是正确的。

创建

Trie.new(@level + 1),返回值并分配给@hash[letter],然后返回相同的值,并将其分配给trie.

执行结束时,trie@hash[letter]都会指向同一个新创建的Trie实例。

如果要创建新对象,则需要多次分配,需要将其缓存到某处(例如,用于记忆),但同时需要在同一方法中重用该变量并且要使用捷径。

假设您在同一范围内使用新创建的对象需要3行。您可以@hash[letter]访问该对象,但trie更短。当然,这只是可能的用法之一。

答案 2 :(得分:1)

是的,你是对的。

从右到左,每个代码块都在赋值之前执行

示例:

variable = nil
hash = {}

variable = hash[:key] = String.new("text")

variable #=> "text"
hash     #=> {:key => "text"}

答案 3 :(得分:1)

你说得对,多项任务是正确的。这样做的原因是赋值构造的左侧必须是单个文字标记:在赋值foo = bar中,bar可能具有任意复杂性,但foo必须是单一令牌;将一些复杂的表达式分配给单个名称是有意义的,但是为复杂的表达式赋值是没有意义的。所以如果你有a = b = c,那么a = (b = c)是理解它的唯一方法,那就是Ruby的工作方式。

关于将表保存为哈希值的问题可能对象太大了,这并不重要,因为所有保留的只是指向对象的指针。