문제

.NET 4 베타 2에는 새로운 Numerics 네임 스페이스가 있습니다. struct BigInteger. 그만큼 선적 서류 비치 내가 예상했던 것처럼 불변의 유형이라고 말합니다.

그러나 나는 점유 후 운영자에게 약간 혼란스러워합니다 (++). 이것은 확실하게 값을 돌연변이하는 것 같습니다. 다음과 같은 루프가 작동합니다.

static BigInteger Factorial(BigInteger n)
{
    BigInteger result = BigInteger.One;
    BigInteger b = BigInteger.One;

    while (b <= n)
    {
        result = result * b;
        b++;  // immutable ?
    }
    return result;
}

이것이 MSDN이 증분 연산자에 대해 말하는 것입니다.

Biginteger 객체는 불변이기 때문에 증분 연산자는 값이 값으로 표시되는 Biginteger 객체보다 하나 인 새로운 BigInteger 객체를 만듭니다. 따라서 증가하는 반복 호출은 비용이 많이들 수 있습니다.

모두 잘하고 괜찮아, 내가 사용해야한다면 이해했을 것이다. b = b++ 그러나 분명히 ++ 그 자체로는 값을 변경하기에 충분합니다.

이견있는 사람?

도움이 되었습니까?

해결책

연산자 ++ 그리고 -- 정상 측면에서 구현됩니다 + 그리고 - 실제로 운영자 : 실제로 :

b++;

다음과 같습니다.

var temp = b;
b = b + 1;
<use temp for the expression where b++ was located>

이제 언급 한 바와 같이, 이것은 불변성을 깨뜨리는 것처럼 보일지 모르지만 그렇지 않습니다.

대신이 코드를 다음과 같이보아야합니다.

var temp = b;
b = BigInteger.op_Add(b, 1); // constructs a new BigInteger value
<use temp ...>

이것은 두 개의 메모리, 원래의 biginteger 값과 새로운 객체를 B로 참조했습니다. 이것이 다음 코드에서 발생하는 것인지 쉽게 확인할 수 있습니다.

var x = b;
b++;
// now inspect the contents of x and b, and you'll notice that they differ

따라서 원래 객체는 변하지 않았으므로 불변성을 깨뜨리지 않으며 질문의 새로운 부분에 응답하기 위해서는 스레드 안전이어야합니다.

이것은 현에 일어나는 것과 같은 것입니다.

String s1 = s2;
s2 += "More";
// now inspect s1 and s2, they will differ

다른 팁

Biginteger는 불변이기 때문에 B ++는 다음과 같습니다.

BigInteger temp=b;
b=temp+1;

이 작업 후에는 GC에 의해 온도가 재활용되고 메모리가 해제됩니다.

BigInteger b = BigInteger.One;

b++;  // immutable ?

예제 B는 변수이며, 이는 현재 메소드의 스택 프레임에 메모리 슬롯 일뿐입니다. 초기화되고 B ++는 B를 가져와 새로운 biginteger (증가 된 값)를 생성하고 반환합니다. 변수 B는 이제 반환 된 새로운 biginteger의 상태를 가지고 있습니다.

내부 상태가 변하지 않는 힙에 객체가 있기 때문에 참조 유형을 처리 할 때 개념으로서 정직하게 불변성이있어서, 작동/메소드가 다른 상태의 새 개체를 반환하면 일종의 분명합니다. 객체 참조 평등을 수행 할 수 있습니다.

값 유형의 경우 힙에 객체가 없으므로 메모리에 슬롯이 있습니다.

좋아요,하지만 BigInteger에 정의 된 단수 부정 연산자는 어떻습니까?

public static BigInteger operator -(BigInteger value)
{
    value._sign = -value._sign;
    return value;
}

불변성 패턴을 깨고 biginteger 객체를 직접 돌연변이하는 것으로 보입니다. 그래서

b = -b;

실제로 새 개체를 반환하지 않고 기존 Biginteger를 제자리에 변경합니다.

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