Почему замыкания, вызываемые из не указательных значений, не будут правильно добавлены в срезы? - PullRequest
0 голосов
/ 18 мая 2019

Это аргумент в go1.12.3 linux/amd64.

Добавлено два замыкания к срезу s, содержащему функцию через переменную x. Закрытие получается методом с указателем-приемником типа T. Добавлены два замыкания в срез s, содержащий функцию через переменную x Закрытие получается методом с указателем приемника типа T.

package main

import "fmt"

type T struct {
    X int
}

func (t *T) f() func() {
    return func() { fmt.Println(t.X) }
}

func good() {
    s := []func(){}

    x := &T{1}
    s = append(s, x.f())

    x = &T{2}
    s = append(s, x.f())

    s[0]() // => 1
    s[1]() // => 2
}

func bad() {
    s := []func(){}

    x := T{1}
    s = append(s, (&x).f())  // Even if it rewrites to append(s, x.f()), the result is the same.

    x = T{2}
    s = append(s, (&x).f())

    s[0]() // => 2 WHY!?
    s[1]() // => 2
}

func main() {
    good()
    bad()
}

https://play.golang.org/p/j-818FZELQb

Из двух приведенных выше функций good() работает как положено. В хорошем s[0]() выполняет T{1}.f()(), а s s[1]() выполняет T{2}.f()(). Однако bad() запускает s[0]() и s[1]() запускает T{2}.f()(). Даже если я добавил элемент в срез, не перезаписывая его!

Понятия не имею, что вызвало такое поведение. Разве переменная x не имеет значения типа T вместо указателя на значение типа T? Или я не знаю спецификацию вызова append?

Пожалуйста, дайте мне совет.

1 Ответ

3 голосов
/ 18 мая 2019

Потому что в плохом случае у вас есть только одна переменная x типа T и одна переменная имеет только один адрес, и, следовательно, ваш слайс s всегда содержитта же функция, работающая с той же переменной, которая имеет значение 2, когда вы начинаете вызывать функции.

(В общем, у вас есть две разные переменные типа T. Вы повторно используете переменную (x) извведите * T, но у вас еще есть два разных T с разными значениями.)

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