Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用默认对象填充ruby数组_Ruby - Fatal编程技术网

用默认对象填充ruby数组

用默认对象填充ruby数组,ruby,Ruby,假设我在ruby中有一个类计数器,定义为 class Counter attr_accessor :starting_value def initialize(starting_value) @starting_value = starting_value end def tick @starting_value = @starting_value + 1 end end 我想用这个对象填充一个数组,使用一个默认参数,如

假设我在ruby中有一个类计数器,定义为

class Counter
    attr_accessor :starting_value
    def initialize(starting_value)
        @starting_value = starting_value
    end

    def tick
        @starting_value = @starting_value + 1
    end
end
我想用这个对象填充一个数组,使用一个默认参数,如下所示: 计数器\u arr=Array.new5,计数器.new0

这几乎就是我想要的,只是我现在有一个数组,其中包含5次相同的计数器实例,而不是一个包含5个新计数器的数组。当我运行代码时

counter_arr = Array.new(5, Counter.new(0)) 
counter_arr[0].tick
counter_arr.each do |c|
    puts(c.starting_value)
end
I输出

1
1
1
1
1
而不是

1
0
0
0
0
我想知道,用一个对象的多个新实例初始化数组的ruby式方法是什么?

试试看

counter_arr = Array.new(5) { Counter.new(0) } 
试一试


如果人们不熟悉普遍使用对象尊重的语言,那么在学习Ruby时首先遇到的一个主要障碍就是这些语言是如何工作的

数组是对零个或多个其他对象的引用的集合。这些对象不一定是唯一的,在某些情况下它们都是相同的。您正在此处创建这样一个对象:

counters = Array.new(5, Counter.new(0))
这将创建一个单一计数器对象,并用它填充数组的所有5个插槽。之所以会出现这种情况,是因为在调用方法之前会对方法的参数求值一次。您可以测试以下内容:

counters.map(&:object_id)
返回数组中每个对象的唯一对象ID。它们是随机值,每个过程是不同的,但它们是相同的

解决此问题的方法是使用块初始值设定项:

counters = Array.new(5) do
  Counter.new(0)
end
这不会插入相同的对象,而是每次对该块求值的结果,因为这会初始化一个新的计数器对象,所以对象将是唯一的

整理此问题的一种方法是调整计数器对象,使其具有正常默认值:

class Counter
  def initialize(initial = nil)
    @value = initial.to_i
  end

  def tick
    @value += 0
  end
end

这样做的好处是可以接受任意值,即使这些值不一定是正确的类型。现在计数器。新的“2”将与自动转换的值一起工作。这是Duck类型的基本原则。如果它能给你一个数字,那就等于一个数字。

如果人们不熟悉普遍使用对象尊重的语言,那么在学习Ruby时首先遇到的主要障碍之一就是这些语言的工作方式

counter_arr = ([-> { Counter.new(0) }] * 5).map &:call
数组是对零个或多个其他对象的引用的集合。这些对象不一定是唯一的,在某些情况下它们都是相同的。您正在此处创建这样一个对象:

counters = Array.new(5, Counter.new(0))
这将创建一个单一计数器对象,并用它填充数组的所有5个插槽。之所以会出现这种情况,是因为在调用方法之前会对方法的参数求值一次。您可以测试以下内容:

counters.map(&:object_id)
返回数组中每个对象的唯一对象ID。它们是随机值,每个过程是不同的,但它们是相同的

解决此问题的方法是使用块初始值设定项:

counters = Array.new(5) do
  Counter.new(0)
end
这不会插入相同的对象,而是每次对该块求值的结果,因为这会初始化一个新的计数器对象,所以对象将是唯一的

整理此问题的一种方法是调整计数器对象,使其具有正常默认值:

class Counter
  def initialize(initial = nil)
    @value = initial.to_i
  end

  def tick
    @value += 0
  end
end

这样做的好处是可以接受任意值,即使这些值不一定是正确的类型。现在计数器。新的“2”将与自动转换的值一起工作。这是Duck类型的基本原则。如果它能给你一个数字,那就和一个数字一样好。

不要忘记像@start\u value+=1这样的语法特性。这通常不会太冗长,并避免了印刷错误。此代码与中回答此问题的示例几乎完全相同。不要忘记诸如@starting_value+=1之类的语法功能。这通常不会太冗长,也避免了印刷错误。这段代码与中回答这个问题的示例几乎完全相同。这是一个非常疯狂的解决方案,但至少很新颖。我认为其他答案提供了更清晰的解决方案,但是我仍然对这里发生的事情感到好奇,这是厄尔索斯由内而外表达的答案。首先,我对@tadman的答案投了赞成票,然后我回忆起我是这里的“出于好奇的小丑”。因此:计数器构造函数用一个进程包装以延迟其执行,然后在此进程中创建一个大小为1的数组,然后使用数组*将此数组扩展为5个元素,最后通过调用进程将其映射到实际计数器。这是一个非常疯狂的解决方案,但它至少是新颖的。我认为其他答案提供了更清晰的解决方案,但我仍然对这里发生的事情感到好奇。这是厄尔索斯从里到外表达的答案。好吧,首先我对@tadman的答案投了赞成票,然后我回忆起我是这里的“只是出于好奇的小丑”。因此:计数器构造函数用一个proc包装以延迟其执行,然后在此proc中创建一个大小为1的数组,然后使用array*将此数组扩展为5个元素,最后通过调用procs将其映射到实际计数器。谢谢!这段代码实际上是我写过的ruby的前21行代码,所以我非常感激
counter_arr = ([-> { Counter.new(0) }] * 5).map &:call

改进。希望对你有用。看起来你已经开始跑步了,这很好。答案很清楚。可能def initializeinitial=0@值=初始值;结束。@CarySwoveland我尝试将默认值设置为零,因为有时这种类型的值会无意中通过0给出了一种错误的置信度,即默认情况下它将被强制为0,但如果未指定参数,则它仅为0,这是一个微妙但重要的区别。您不希望意外的nil引发异常?谢谢!这段代码实际上是我写过的ruby的前21行代码,所以我非常感谢所有的改进。希望这对你有用。看起来你已经开始跑步了,这很好。答案很清楚。可能def initializeinitial=0@值=初始值;结束。@CarySwoveland我尝试将默认值设置为零,因为有时这种类型的值会无意中通过0给出了一种错误的置信度,即默认情况下它将被强制为0,但如果未指定参数,则它仅为0,这是一个微妙但重要的区别。您不希望无意中的nil引发异常吗?