为什么我不能在 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
我也在 String
和 Char
上试过了,我得到了同样的编译器错误:Error: can't change the value of self
答案是:self
是什么?答案取决于 class:
- 如果它是一个
Value
(Int32
, Char
),那么它的值(你想改变的)在传递时被复制:没有一个地方在您可以去哪里执行更改的内存。
- 如果它是一个
Reference
(String
和大多数用户定义的 classes),那么 self
是一个指向对象的指针。这意味着如果您能够更改 self
,那么您正在修改 指针 ,而不是其内容。
最后一点,this applies to Ruby too。
Beta Ziliani 的回答很好,着眼于大局。
对于这个特定的例子,答案其实很简单:Crystal 中的基本类型是不可变的。
所以不可能改变原始类型实例的值。变异方法总是必须 return 一个 new 值。然后可以将该值再次分配给同一个变量。
解决方法是将基元包装在结构中。或者作为一种不安全的替代方法,您可以将指向具有原始值的变量的指针传递给方法。然后该方法可以为该指针赋值。
如果我尝试实现一个额外的方法,它不会改变 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
我也在 String
和 Char
上试过了,我得到了同样的编译器错误:Error: can't change the value of self
答案是:self
是什么?答案取决于 class:
- 如果它是一个
Value
(Int32
,Char
),那么它的值(你想改变的)在传递时被复制:没有一个地方在您可以去哪里执行更改的内存。 - 如果它是一个
Reference
(String
和大多数用户定义的 classes),那么self
是一个指向对象的指针。这意味着如果您能够更改self
,那么您正在修改 指针 ,而不是其内容。
最后一点,this applies to Ruby too。
Beta Ziliani 的回答很好,着眼于大局。
对于这个特定的例子,答案其实很简单:Crystal 中的基本类型是不可变的。 所以不可能改变原始类型实例的值。变异方法总是必须 return 一个 new 值。然后可以将该值再次分配给同一个变量。
解决方法是将基元包装在结构中。或者作为一种不安全的替代方法,您可以将指向具有原始值的变量的指针传递给方法。然后该方法可以为该指针赋值。