Как создать новую структуру и использовать ее исходное значение в качестве члена новой структуры - PullRequest
2 голосов
/ 04 марта 2020

Я пытаюсь создать новую структуру и использовать ее исходное значение в качестве члена новой структуры. Тем не менее, оба они в конечном итоге являются одной и той же ссылкой (то есть payload и payload.prev), и это вызывает бесконечную рекурсию в моем коде. Я ценю любую помощь или подсказку.

package main

type Sieve struct {
    prime int
    prev  *Sieve
}

func Test(payload *Sieve, n int) {
    if payload.prime*(n/payload.prime) == n {

    } else if payload.prev == nil {
        println(n)
        // payload and payload.prev end up being the same reference
        // and it causes infinite loop
        *payload = Sieve{
            prime: n,
            prev:  payload,
        }
    } else {
        Test(payload.prev, n)
    }
}

func main() {
    var p = Sieve{
        prev:  nil,
        prime: 2,
    }

    println(2)

    for i := 2; i < 10; i++ {
        Test(&p, i)
    }
}

Ответы [ 3 ]

2 голосов
/ 04 марта 2020

Вы хотите обновить указатель «полезной нагрузки», чтобы он указывал на адрес новой структуры. Создайте свою новую структуру следующим образом:

payload = &Sieve{
            prime: n,
            prev:  payload,
        }
1 голос
/ 05 марта 2020

Перед перезаписью структуры Sieve, на которую указывает payload, сделайте ее копию:

p := *payload

И теперь вы можете назначить новое значение структуры Sieve, сохраняя адрес копии как его prev поле:

*payload = Sieve{
    prime: n,
    prev:  &p,
}

С этим изменением ваше приложение запускается и правильно выводит простые числа от 2 до 10 (попробуйте на Go Playground ):

2
3
5
7
1 голос
/ 05 марта 2020

С помощью приведенного ниже кода вы не создаете новый экземпляр Sieve, а настраиваете существующий экземпляр Sieve так, чтобы он указывал на себя:

*payload = Sieve{
            prime: n,
            prev:  payload,
        }

Если вы хотите создать пу sh на payload на один уровень ниже, вы можете сделать это:

p:=*payload
*payload = Sieve {
  prime: n,
  prev: &p}

Сначала будет назначено содержимое payload на p, а затем будет перезаписано содержимое payload для указания на p.

С другой стороны, если вы хотите создать новый payload, указывающий на старый, используйте:

payload = Sieve { 
   prime: n,
   prev: payload }

Затем вы должны вернуть / использовать это новый указатель payload.

...