Как получить указатель возвращаемого значения из вызова функции?

Мне просто нужен указатель на time.Time, поэтому код ниже кажется недействительным:

./c.go:5: не могу принять адрес времени. Теперь ()

Мне просто интересно, почему? Есть ли способ сделать это, кроме как сначала выполнить назначение переменной и взять указатель на переменную?

package main import "time" func main() { _ = &time.Now() } 

Вероятно, неудовлетворительный ответ: «Вы не можете этого сделать, потому что спецификация говорит так». Спектр говорит, что для использования & на что-то он должен быть адресуемым или составным литералом, и для его адресации он должен быть «переменным, указателем-указателем или операцией индексирования среза» или «селектором полей» адресного структурного операнда; операцию индексирования массива адресного массива ». Вызовы функций и вызовы методов, безусловно, не входят в список.

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

Или я мог бы передумать, и они просто не хотели иметь специальный случай для функций, которые возвращают одно значение по сравнению с функциями, которые возвращают несколько 🙂

Вы не можете напрямую принимать адрес вызова функции (или, точнее, возвращаемое значение (ы) функции), как описано hobbs.

Есть другой способ, но он уродлив:

 p := &[]time.Time{time.Now()}[0] fmt.Printf("%T %p\n%v", p, p, *p) 

Выход ( Go Playground ):

 *time.Time 0x10438180 2009-11-10 23:00:00 +0000 UTC 

Здесь происходит создание struct с литералом, содержащим один элемент (возвращаемое значение time.Now() ), срез индексируется (0- й элемент) и берется адрес 0- го элемента.

Так что просто используйте локальную переменную:

 t := time.Now() p := &t 

Или вспомогательная функция:

 func ptr(t time.Time) *time.Time { return &t } p := ptr(time.Now()) 

Которая также может быть анонимной функцией с одним лайнером:

 p := func() *time.Time { t := time.Now(); return &t }() 

Или как альтернатива:

 p := func(t time.Time) *time.Time { return &t }(time.Now()) 

Для получения еще большего количества альтернатив см.

Как сделать буквенный * int64 в Go?

  • Лучшая практика управления репутацией Голанга
  • Как разбить длинную строку кода в Голанге?
  • Доступ к структуре на карте (без копирования)
  • go работает отлично, но не работает
  • невозможно загрузить, $ GOPATH не установлен
  • Почему я не могу назначить * Struct на * интерфейс?
  • Как читать ввод с консоли?
  • Как использовать C ++ в Go?
  • Изменение значений во время итерации в golang
  • Что это за "foo. (Bar.Baz)" вещь в коде Go?
  • Go 1.3 Сборщик мусора, не отбрасывающий серверную память обратно в систему
  • Давайте будем гением компьютера.