2015-02-11 2 views
1

Так, согласно спецификации, значения в функции отсрочки оцениваются при вызове функции отсрочки, но действия не выполняются до тех пор, пока функция закрытия не вернется. Я получаю это и понимаю все 'для i: = 0; i < 4; i ++ пример отсрочки печатает' вещь.golang defer не оценивает, когда ожидается

Однако при попытке использовать временно отложить до присвоить значение переопределения (назначить макс м в очередь длины д), то убедитесь, что значение сбрасывается, когда я сделал (пример упрощен для демонстрации):

type tss struct { 
    q int 
    m int 
} 

func (t *tss) test() { 
    if true { 
     defer func() { 
      t.q=t.q  //this should evaluate to 't.q = 50' right? 
      fmt.Println("assigned",t.q,"to t.q") 
     }() 
     t.q = t.m 
    } 
    fmt.Printf("q=%v, m=%v\n", t.q, t.m) 
} 

func main() { 
    ts := tss{50,1} 
    fmt.Printf("q=%v, m=%v\n", ts.q, ts.m) 
    ts.test() 
    fmt.Printf("q=%v, m=%v\n", ts.q, ts.m) 
} 

Я бы ожидать, чтобы получить результат:

q=50, m=1 
q=1, m=1 
assigned 50 to t.q 
q=50, m=1 

но фактический выход есть:

q=50, m=1 
q=1, m=1 
assigned 1 to t.q 
q=1, m=1 

Таким образом, казалось бы, значения оцениваются в неподходящее время. Тем не менее, когда я свалка t.q в переменном первый и переместите его назначение за пределами отложенной функции, а также изменить функцию тестирования выглядеть следующим образом:

func (t *tss) test() { 
    if true { 
     qtmp := t.q 
     defer func() { 
      //assigning qtmp here still assigns 1 back to t.q 
      t.q=qtmp 
      fmt.Println("assigned",t.q,"to t.q") 
     }() 
     t.q = t.m 
    } 
    fmt.Printf("q=%v, m=%v\n", t.q, t.m) 
} 

Я получаю ожидаемый результат выше, где 50 назначенный.

Удалось ли мне отключить ошибку, или есть что-то о назначении значения в отложенном func, которое мне не хватает?

Возможно отметить, если я прохожу TQ в качестве аргумента функции, которая работает так:

func (t *tss) test() { 
    if true { 
     defer func(q int) { 
      t.q=q 
      fmt.Println("assigned",t.q,"to t.q") 
     }(t.q) 
     t.q = t.m 
    } 
    fmt.Printf("q=%v, m=%v\n", t.q, t.m) 
} 

EDIT: здесь полная версия с использованием метода в ответ:

type tss struct { 
    q int 
    m int 
} 

func (t *tss) test() { 
    if true { 
     defer func(q int) { 
      t.q=q  //this will correctly evaluate to 't.q = 50' 
      fmt.Println("assigned",t.q,"to t.q") 
     }(t.q) 
     t.q = t.m 
    } 
    fmt.Printf("q=%v, m=%v\n", t.q, t.m) 
} 

func main() { 
    ts := tss{50,1} 
    fmt.Printf("q=%v, m=%v\n", ts.q, ts.m) 
    ts.test() 
    fmt.Printf("q=%v, m=%v\n", ts.q, ts.m) 
} 

и правильный выход:

q=50, m=1 
q=1, m=1 
assigned 50 to t.q 
q=50, m=1 

ответ

7

Так что я ответил на мой собственный вопрос, в то время как корректура мой пост. Вместо того, чтобы удалять его, чтобы скрыть мое смущение, я оставлю его на случай, если другие будут испытывать такую ​​же путаницу.

Отложенная функция оценивает любые ARGUMENTS функции, когда она вызывается. Он не сразу оценивает значения внутри тела функции. Поэтому внутренние задания выполняются, когда происходят отложенные действия.

Итак:

  1. код выполняется
  2. Перенести утверждение встречаются
  3. golang хранит значение аргументов для последующего
  4. тела Отложенного FUNC является полностью игнорировалось
  5. остальной части код запускается до конца прилагаемой функции
  6. Отложенная функция выполняется с использованием значений хранимых аргументов

-Mike

+2

Примечание для будущего: Пожалуйста, не подписывайте свои сообщения. Рядом с каждым почтовым ящиком находится поле, в котором указано ваше имя пользователя, поэтому подписка не требуется (и не рекомендуется, как и любая форма приветствия). – fuz

2

Хорошая работа, отвечая на свой вопрос.Я думаю, что это стоит того, чтобы показать, какая коррекция будет для вашей первоначальной попытки будущих читателей.

func (t *tss) test() { 
    if true { 
     defer func(q int) { 
      t.q = q //this should evaluate to 't.q = 50' right? 
      fmt.Println("assigned", t.q, "to t.q") 
     }(t.q) 
     t.q = t.m 
    } 
    fmt.Printf("q=%v, m=%v\n", t.q, t.m) 
} 

ВЫВОД

q=50, m=1 
q=1, m=1 
assigned 50 to t.q 
q=50, m=1