Значение go big.Int изменяется, когда значение указывает на другой экземпляр - PullRequest
0 голосов
/ 23 марта 2020

Я столкнулся с необъяснимым поведением go big.Int при указании экземпляра одного big.Int на другой. Я осведомлен, что для того, чтобы установить значение экземпляра bit.Int для другого, нужно использовать установщики Int.SetXXX, потому что они фактически приводят к копированию нижележащего среза abs в big.Int в новый выделенный массив. Однако, оставив это на мгновение, я хотел бы знать , почему происходит следующее поведение.

Рассмотрим следующее:

Неправильный пример (базовое значение мутирует) :

func main() {
    v1p := big.NewInt(1)
    v2p := big.NewInt(2)

    v1 := *v1p
    v2 := *v2p

    v2 = v1

    v1.SetInt64(3)

    fmt.Println(v1.Int64(), v2.Int64())
}

(запустить здесь: https://play.golang.org/p/WxAbmGdKG9b)

Правильный пример (значение не изменяется):

func main() {
    v1p := big.NewInt(1)
    v2p := big.NewInt(2)

    v1 := *v1p
    v2 := *v2p

    v2.Set(v1p)

    v1.SetInt64(3)

    fmt.Println(v1.Int64(), v2.Int64())
}

(запустить здесь: https://play.golang.org/p/16qsGhwHIWf)

Если я правильно понимаю, следующее должно по существу продемонстрировать, что происходит в неправильном примере:

func main() {
    var a, b *int // analogous to the 2 big.Int pointers returned
    c, d := 3, 3
    a = &c // we set the pointers to point to something we can then dereference
    b = &d

    e := *a // e and f should now point to the values pointed to by the pointers
    f := *b

    // the rest is self-explanatory
    e = f

    c = 5
    d = 4

    fmt.Println(a, b, c, d, e, f)
}

(запустить здесь: https://play.golang.org/p/cx76bnmJhG7)

Мое единственное предположение заключается в том, что каким-то образом при копировании содержимого структуры на v2 в примере Wrong происходит то, что срез abs не получить глубокое копирование, но что хранилище, на которое оно ссылается, фактически является тем же хранилищем, на которое указывает фрагмент в v1.

Действительно ли это происходит? Это ожидаемое поведение в соответствии с языком spe c тоже?

1 Ответ

0 голосов
/ 24 марта 2020

Как отметили icza и Volker, поскольку при разыменовании указателя big.Int структура заголовка слайса фактического значения копируется, указывая на одно и то же базовое значение, в результате получается, что на один и тот же базовый массив ссылаются из нескольких слайсов, в результате чего один изменяет другой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...