문제

다음 코드는 "8", "111"및 "999"를 인쇄 할 것으로 예상했습니다. 각 A, B, C 및 D는 동일한 메모리 위치를 가리 킵니다. 그 중 하나를 통해 위치를 바꾸면 왜 다른 사람이 변경하지 않겠습니까? 분명히 내 논리는 가난하거나 무언가를 간과했습니다. 대신 "7", "7"및 "8"을 인쇄합니다.

왜요?

a=b=c=d=7
     b  =  8
     puts d

     c  = 111
     puts a

     d  =  999
     puts b

설명

내 혼란의 이유는 예입니다 책 (20 페이지). 그것들은 그 값을 비슷하게 변경하지만 위에서 제안한 결과를 얻습니다. 우리는 같은 문제에 대해 말하고 있습니까?

도움이 되었습니까?

해결책

a=b=c=d=7
# a, b, c and d points to the same integer object "7"
     b  =  8
# b now points to a new object "8"
# "=" does not change the value of the pointer integer, 
# it assings a new reference like in the line above
     puts d
# obviously, d still points to "7"

     c  = 111
# c now points to another integer object "111"
     puts a
# a still points to "7"

     d  =  999
# d now points to a new integer object "999"
     puts b
# b still points to "8"

루비에서는 정수 객체가 불변이기 때문에 정수를 여러 참조에 할당하고 그 후에 그 값을 변경할 수 없습니다.

@pts가 제안한 것처럼 배열을 사용하여 배열이 변하기 때문에 값을 변경할 수 있으므로 정수 참조를 포장해야합니다.

a=b=c=d=[7]
b[0] = 8
puts d[0]
c[0] = 111
puts a[0]
d[0] = 999
puts b[0]

설명:

C ++ 배경에서 온 경우 C ++가 동일한 구문으로 2 가지를 수행하고 참조를 할당하고 참조 된 값을 변경하기 때문에 이상 할 수 있습니다.

int a = 10; // creates an int on the stack with value 10
int& b = a; // creates a reference to an int and references the a variable
b = 5; // change the value referenced by b (so a) to 5
// a and b now hold the value 5

루비에서는 기준이 변이 가능하고 정수는 (정확히 C ++와 반대)가 아닙니다. 따라서 참조를 할당하면 참조 값이 아닌 참조가 변경됩니다.

또 다른 해결책은 변한 정수 인 클래스를 만드는 것입니다.

class MutableInteger
  attr_writer :value
  def initialize(value)
    @value = value
  end
  def inspect
    value
  end
  def to_i
    value
  end
  def to_s
    value
  end
end

a = b = MutableInteger.new(10)
a.value = 5
puts b
# prints 5

다른 팁

예상되는 출력을 얻는 가장 쉬운 방법은 단일 요소 배열을 사용하는 것입니다.

a=b=c=d=[7]
b[0] = 8
puts d[0]
c[0] = 111
puts a[0]
d[0] = 999
puts b[0]

A와 B가 동일한 개체를 참조하는 경우 a.__id__ == b.__id__ .

그들은 같은 메모리 위치를 가리키지 않습니다. 루비는 참조로 통과하지 않습니다.

첫 번째 줄 후에 A, B, C 및 D는 모두 동일한 FixNum 객체 (값 7)를 가리 킵니다. 그러나 B = 8을 실행할 때 B는 이제 새로운 FixNum 객체 (값 8)를 가리 킵니다.

효과적으로 기존 객체를 변형시키는 대신 B를 새 개체에 할당합니다. 이것이 예상대로 변경이 전파되지 않는 이유입니다.

C ++와 비교하는 경우, 이것은 참조별로 할당하는 대신 값별로 포인터를 할당하는 것과 같습니다.

나는 독서를 강력히 추천합니다 C 참조 자바와 루비는 그렇지 않습니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top