У меня есть struct, который состоит из пользовательского time.Time, определенного для того, чтобы иметь собственный интерфейс MarshalJSON(), следуя предложению этот ответ:
type MyTime time.Time
func (s myTime) MarshalJSON() ([]byte, error) {
t := time.Time(s)
return []byte(t.Format(`"20060102T150405Z"`)), nil
}
Я определяю тип MyStruct с полями ThisDate и ThatDate типа *MyTime:
type MyStruct struct {
ThisDate *MyTime `json:"thisdate,omitempty"`
ThatDate *MyTime `json:"thatdate,omitempty"`
}
Насколько я понимаю, мне нужно использовать *MyTime, а не MyTime, поэтому тег omitempty будет иметь эффект, когда я буду MarshalJSON переменную этого типа, следуя предложению этот ответ.
Я использую библиотеку с функцией, которая возвращает мне struct с некоторыми полями типа *time.Time:
someVar := Lib.GetVar()
Я попытался определить переменную типа MyStruct следующим образом:
myVar := &MyStruct{
ThisDate: someVar.ThisDate
ThatDate: someVar.ThatDate
}
Естественно, это дает мне ошибку компиляции:
cannot use someVar.ThisDate (variable of type *time.Time) as *MyTime value in struct literal ...
Я пробовал приведение типов someVar.ThisDate с */& и без них, но безуспешно. Я думал, что следующее будет работать:
myVar := &MyStruct{
ThisDate: *MyTime(*someVar.ThisDate)
ThatDate: *MyTime(*someVar.ThatDate)
}
Но это дает мне другую ошибку компиляции:
invalid operation: cannot indirect MyTime(*someVar.ThisDate) (value of type MyTime) ...
Кажется, мне, вероятно, не хватает базового понимания указателей и разыменований в Go. Тем не менее, я хотел бы избежать поиска конкретного решения моей проблемы, которое сводится к сочетанию необходимости сделать omitempty эффект и кастом MarshalJSON.
Это очень полезно, спасибо! Не могли бы вы объяснить этот синтаксис? Я видел его много раз, и я даже не знаю, как его искать, чтобы найти документацию о нем. Возможно, подойдет даже ссылка на нужное место в tour.golang.org.
Если вы понимаете концепцию приоритета оператора или порядка оценки, вы можете увидеть, что *T(v) может быть интерпретировано двояко и, следовательно, неоднозначно, поэтому к избежать двусмысленности вы можете пояснить свое намерение, добавив круглые скобки (*T)(v).
Это отличное объяснение @mkopriva - именно то, чего мне не хватало. Пожалуйста, не стесняйтесь вставлять эти слова в ответ, который я отмечу как принятый.
В Go вообще нет приведения типов.
Пожалуйста, найдите время, чтобы также усвоить то, что сказал Флимзи: в Go нет type_casting_ — то есть принудительной переинтерпретации значения одного типа как значения другого. Вместо этого в Go есть тип конверсии;, который отличается тем, что позволяет преобразовывать значения между совместимыми типами, где совместимость примерно означает «представление значений, которые имеют одинаковые макеты памяти для своих данных».
Спасибо @kostix, я отредактировал заголовок вопроса.

Проблема в неоднозначном синтаксисе *T(v) или чего-то еще, что вы там пробовали. спецификация Голанга дает полезные примеры преобразования типов, цитируя:
*Point(p) // same as *(Point(p))
(*Point)(p) // p is converted to *Point
Поэтому, поскольку *Point необходимо, следует использовать *T(v).
(*T)(v) для *Point; чтобы получить балл, это *(*T)(v).
(*MyTime)(someVar.ThisDate)someVar.ThisDateуже*time.Timeверно? так что вам не нужно*перед ним. Кроме того, при преобразовании в типы указателей, то есть*T, я бы рекомендовал всегда помещать тип указателя в дополнительные круглые скобки, то есть(*T). play.golang.com/p/jH9Q07sizID