【发布时间】:2019-05-25 19:21:49
【问题描述】:
我有一个struct,它包含一个自定义的time.Time,因为它有一个自定义的MarshalJSON()接口,遵循this answer的建议:
type MyTime time.Time
func (s myTime) MarshalJSON() ([]byte, error) {
t := time.Time(s)
return []byte(t.Format(`"20060102T150405Z"`)), nil
}
我用ThisDate 和ThatDate 类型为*MyTime 的字段定义了一个MyStruct 类型:
type MyStruct struct {
ThisDate *MyTime `json:"thisdate,omitempty"`
ThatDate *MyTime `json:"thatdate,omitempty"`
}
据我了解,我需要使用*MyTime 而不是MyTime,所以omitempty 标记将在我MarshalJSON 这种类型的变量之后产生效果,遵循this answer 的建议。
我使用的库有一个函数,它返回一个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。
【问题讨论】:
-
(*MyTime)(someVar.ThisDate)someVar.ThisDate已经是*time.Time对吗?所以你不需要前面的*。此外,当转换为指针类型时,即*T,我建议始终将指针类型放在额外的括号中,即(*T)。 play.golang.com/p/jH9Q07sizID -
这很有帮助,谢谢!您能否进一步解释一下这种语法?我已经看过很多次了,我什至不知道如何搜索它以找到有关它的文档。也许甚至可以链接到tour.golang.org 中的正确位置。
-
golang.org/ref/spec#Conversions 如果类型以运算符 * 或
-
如果您了解运算符优先级或求值顺序的概念,您可以看到
*T(v)可以有两种解释,因此是模棱两可的,因此避免歧义 您可以通过添加括号(*T)(v)来明确您的意图。 -
这是一个很好的解释@mkopriva - 正是我所缺少的。请随时将这些词放入我将标记为已接受的答案中。
标签: go struct type-conversion