为什么我不能在 Int32 上更改 self 的值

Why can't I change the value of self on Int32

如果我尝试实现一个额外的方法,它不会改变 self 的值,在 Int32 它有效:

struct Int32
    def double
        self * 2
    end
end

x = Int32.new 2
p! x.double # => 4

但是,当我尝试更改 self 时,编译器立即给我一个错误,为什么?有没有办法做到这一点,或者在 Crystal 中完全不可能?

struct Int32
    def six
        self = 6 # This fails
    end
end

我也在 StringChar 上试过了,我得到了同样的编译器错误:Error: can't change the value of self

答案是:self是什么?答案取决于 class:

  • 如果它是一个Value (Int32, Char),那么它的值(你想改变的)在传递时被复制:没有一个地方在您可以去哪里执行更改的内存。
  • 如果它是一个 ReferenceString 和大多数用户定义的 classes),那么 self 是一个指向对象的指针。这意味着如果您能够更改 self,那么您正在修改 指针 ,而不是其内容。

最后一点,this applies to Ruby too

Beta Ziliani 的回答很好,着眼于大局。

对于这个特定的例子,答案其实很简单:Crystal 中的基本类型是不可变的。 所以不可能改变原始类型实例的值。变异方法总是必须 return 一个 new 值。然后可以将该值再次分配给同一个变量。

解决方法是将基元包装在结构中。或者作为一种不安全的替代方法,您可以将指向具有原始值的变量的指针传递给方法。然后该方法可以为该指针赋值。