test3 печатает ptr as pointer=2020, ptr as value=20 и a=10. Однако весь main из фрагмента не компилируется, если отсутствующая test1 нигде не определена.
Отложенный вызов defer: различия между передачей значений и указателей
test3 печатает ptr as pointer=2020, ptr as value=20 и a=10. Однако весь main из фрагмента не компилируется, если отсутствующая test1 нигде не определена.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо понять, какие данные будет выводить программа, если использовать оператор defer для функций, которые принимают как обычные значения, так и указатели.
func main() {
fmt.Println(test1())
test3()
}
func test3() {
var a int = 10
var b = 20
var ptr *int = &b
defer printInt("a", a)
defer printInt("ptr as value", *ptr)
defer printIntPointer("ptr as pointer", ptr)
a = 1010
*ptr = 2020
}
func changeI(i *int) {
*i = 10
}
func printInt(label string, v int) {
fmt.Printf("%s=%d\n", label, v)
}
func printIntPointer(label string, p *int) {
fmt.Printf("%s=%d\n", label, *p)
}
Ответ
test3 печатает ptr as pointer=2020, ptr as value=20 и a=10. Однако весь main из фрагмента не компилируется, если отсутствующая test1 нигде не определена.
Аргументы defer вычисляются сразу: значения a и *ptr сохраняются как 10 и 20. В третьем вызове сохраняется адрес b, а разыменование происходит уже при выполнении, после записи 2020. Вызовы идут в обратном порядке. Результат test1 нельзя определить по этому фрагменту; changeI здесь вообще не вызывается.