英文:
Assign a time.Date to a *time.Time pointer to test a JSON deserialization
问题
我有一个结构体,其中一个字段被声明为String,但实际上应该存储一个时间。因此,我将其更改为*time.Time
(参见提交),请注意使用指针来绕过",omitempty"
在空日期的情况下并不真正省略值的问题。
到目前为止还好。问题是,现在我正在尝试编写一个代码来测试JSON字符串的正确反序列化,但我无法将结果与以下内容进行比较:
want := Record{Id: 1539, UpdatedAt: time.Date(2014, 01, 15, 22, 03, 04, 0, time.UTC)}
因为UpdatedAt
应该是一个指针*time.Time
,而time.Date
返回的是一个time.Time
。
我不能使用
want := Record{Id: 1539, UpdatedAt: &time.Date(2014, 01, 15, 22, 03, 04, 0, time.UTC)}
因为它会被拒绝(它期望一个指针,而我尝试分配一个结构体)
cannot take the address of time.Date(2014, 1, 15, 22, 3, 3, 0, time.UTC)
这是我的问题。是否有一种方法可以在创建Record
时即时使用time.Date
(而不是将time.Date
分配给一个变量,然后获取指针),和/或解决此问题的方法,以确保在对象序列化/反序列化时可以正确分配空日期的nil值?
英文:
I have a struct, where one of the fields was declared as String, but it was intended to store a Time. Therefore I changed it to *time.Time
(see the commit), note the use of a pointer to bypass the issue where ",omitempty"
doesn't really omit the value in case of an blank date.
So far so good. The problem is that now I'm trying to write a code that tests the correct deserialization of the JSON string, but I can't compare the result with
want := Record{Id: 1539, UpdatedAt: time.Date(2014, 01, 15, 22, 03, 04, 0, time.UTC)}
because UpdatedAt
is expected to be a pointer *time.Time
, whereas time.Date
returns a time.Time
.
I can't use
want := Record{Id: 1539, UpdatedAt: &time.Date(2014, 01, 15, 22, 03, 04, 0, time.UTC)}
because it is indeed rejected (it expects a pointer, I try to assign a struct)
cannot take the address of time.Date(2014, 1, 15, 22, 3, 3, 0, time.UTC)
Here's my question. Is there a way to create a Record
with a time.Date
on the fly (hence without assigning the time.Date
to a variable and then get the pointer) and/or a workaround for the issue that guarantees I can have a proper nil value assigned when the object is serialized/deserialized and the date is blank?
答案1
得分: 13
你不能获取函数返回值的地址,因为你只能获取可以赋值的东西的地址。
可以这样理解:如果你将结果存储在变量中,那么你可以获取该变量的地址,但如果你没有这样做,那么就没有东西可以获取地址了。
英文:
You can't take the address of a function return value because you can only take the address of something that can be assigned to.
Think of it this way: if you store the result in variable, you can then take the address of that variable, but if you don't, then there's nothing you can take the address from.
答案2
得分: 11
你想先将日期值存储在一个变量中,然后使用该变量的指针。
myDate := time.Date(2014, 01, 15, 22, 03, 04, 0, time.UTC)
want := Record{Id: 1539, UpdatedAt: &myDate}
英文:
You want to store the date value in a variable first and then use the pointer of the variable.
myDate := time.Date(2014, 01, 15, 22, 03, 04, 0, time.UTC)
want := Record{Id: 1539, UpdatedAt: &myDate}
答案3
得分: 3
只是为了记录,你可以像这样定义一个函数:
func toTimePtr(t time.Time) *time.Time {
return &t
}
然后可以这样使用:
want := Record{Id: 1539, UpdatedAt: toTimePtr(time.Date(2014, 01, 15, 22, 03, 04, 0, time.UTC))}
英文:
Just for the record, you can define a function like this:
func toTimePtr(t time.Time) *time.Time {
return &t
}
And then do that:
want := Record{Id: 1539, UpdatedAt: toTimePtr(time.Date(2014, 01, 15, 22, 03, 04, 0, time.UTC))}
答案4
得分: 0
你不能获取字面量的地址,因为它们在代码中被内联了(至少这是我目前对原因的理解)。
我在我的测试代码中经常有以下内容:
func literalAddressProvider[T any](s T) *T { return &s }
这对于任何类型都有效(至少我迄今为止尝试过的类型都有效!),例如string
和time.Time
。
你还可以使用lo包在GitHub上的ToPtr()
函数(我撰写本文时已有超过9k个星标)。它的用法相同,你可以写ptr := lo.ToPtr("hello world")
(Go编译器能够推断出T
是字符串类型,所以不需要指定类型,与lo包文档中出现的许多示例相反)。
英文:
You cannot take the address of literals as they get inlined in the code (at least that's my current understanding of the reason).
I often have the following in my test code:
func literalAddressProvider[T any](s T) *T { return &s }
which works for any type (well, all those I have tried so far!). Eg string
and time.Time
.
You can also use the ToPtr()
function of the lo package on github (over 9k stars as I'm writing this post). This works the same, you can write ptr := lo.ToPtr("hello world")
(the go compiler is able to infer T
as string so no need to specify it, contrary to the many examples that appear in the lo package docs).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论