有没有办法在 Ruby 中将舍入浮点数自动分配给变量?

Is there a way to self assign a rounded float to a variable in Ruby?

提问人:Henrique Marques 提问时间:3/9/2023 更新时间:3/12/2023 访问量:103

问:

我想变成什么东西,比如变成.var = var.round(2)var = var + 1var += 1

在 Ruby 中有什么方法可以做到这一点吗?

我已经尝试过方法,但它不像其他方法那样工作。round!gsub!

Ruby 浮点 舍入

评论


答:

-2赞 Rostislav Zhuravsky 3/9/2023 #1

不,这是不可能的,因为某些 Ruby 类的对象是不可变的。

Ruby 提供了一个在 Ruby 虚拟机中返回对象 ID 的方法。或者,您可以使用该方法来判断内存中两个对象是否实际上是相同的对象。#object_idequal?

Hashes、Strings 和 Array 是可变的,而 Symbol、Float 和 Integer 是不可变的。

如果你去 irb,你可以看到这样的东西:

irb(main):009:0> 345.object_id
=> 691
irb(main):010:0> 345.object_id
=> 691
irb(main):011:0> 345.6.equal?(345.6)
=> true
irb(main):012:0> {}.equal?({})
=> false
irb(main):013:0> {}.object_id
=> 100360
irb(main):014:0> {}.object_id
=> 111840

因此,无法更改由变量持有的不可变对象。 唯一的方法是使变量指向另一个对象。

评论

4赞 Stefan 3/9/2023
OP 不想改变浮点数。他们要求使用快捷方式为同一变量分配舍入值。
2赞 Cary Swoveland 3/9/2023 #2

这是一种方法。

class Float
  def ^(arg)
    round(arg)
  end
end

让我们试试吧。

x = 2.12345
x ^ 2   #=> 2.12
x       #=> 2.12345, x is unchanged
x ^= 2  #=> 2.12
x       #=> 2.12, x is assigned the value 2.12

这应该不会引起问题,尽管将来可能会发生变化。Float.instance_methods.include?(:^) #=> false

+=、 等称为赋值表达式,或者更常见的是赋值运算符。 为 分配与 相同的值。请注意,如果是包含此表达式的方法的参数在调用方法中不会发生突变。*=-=x += 2xx = x + 2xx

等号前面的运算符表达式可以是以下任何一种,而不能是其他任何一种:

+  -  *  /  %  **  &  |  ^  <<  >>  &&  ||

其中,以下是实例方法Float

**  %  *  +  -  /

使用其中之一显然是不明智的。

运算符 和 未作为方法实现,因此不能使用它们。剩下的是以下符号或符号对,可以安全地用来代替我上面的方法,至少对于当前(我相信是旧)版本的 Ruby 是这样。&&||^

&  |  ^  <<  >> 

我相信这个问题是学术性的,仅仅是出于好奇心。

评论

1赞 engineersmnky 3/9/2023
哦,恐怖。我至少会选择一种“操作”方法,而不是像.Float^
1赞 Cary Swoveland 3/9/2023
@engineersmnky,非常好的观点。我已经相应地编辑了我的答案。读者:本来我重写了 Float 现有的方法,造成了无穷无尽的麻烦。将方法名称更改为不是 Float 实例方法名称的名称(如 )可避免该问题。+^
1赞 engineersmnky 3/9/2023
好吧,我不能再投赞成票了,但我赞成这个编辑远远超过原来的玷污,我想不出一个合乎逻辑的实现,因为“幂”已经通过Float#+Float#^**
2赞 Pascal 3/9/2023
很高兴你加上“我相信......”到那个答案。我今天学到了一些新东西......但是讨厌在我需要触摸的代码库中看到它。
1赞 3/12/2023
我认为应该注意的是,它实际上在类中用作按位 XOR 运算符。尽管我怀疑内置实现是否会很快发生,但我认为在类中执行操作的能力肯定有一些价值。^Numericexclusive orFloat
0赞 user16452228 3/12/2023 #3

在我看来,您正在尝试做的是就地破坏性地修改或改变变量。有些方法是开箱即用的破坏性方法,而其他方法(如/具有破坏性和非破坏性版本)则具有破坏性和非破坏性版本。gsubgsub!

这里的问题是,Ruby 对类中的任何内容都没有任何破坏性的方法,就像它们对 、 和 类所做的那样。所以,要回答你的问题......不,我不认为在 Ruby 中有什么很好的方法可以做到这一点,而不涉及一些不明智的幕后操作。NumericStringArrayHash