英文:
Copying pointer content in go causing uneccesary overhead?
问题
如果我理解正确的话,*s = *(*State)(&state)
将 &state
处的内容复制到了 s
的地址上(在将 *rawState
强制转换为 *State
之后)。但如果是这样的话,直接执行 s = (*State)(&state)
不是更高效吗?这样就不需要复制,而且 *state
也不会被垃圾回收。或者这种方式可能会导致副作用,改变 s
的值或者其他原因导致这样做吗?谢谢!
完整的函数代码如下:
func (s *State) UnmarshalJSON(b []byte) error {
type rawState State
var state rawState
dec := json.NewDecoder(bytes.NewReader(b))
if s.useJSONNumber {
dec.UseNumber()
}
err := dec.Decode(&state)
if err != nil {
return err
}
*s = *(*State)(&state)
return s.Validate()
}
英文:
If I understood it right, *s = *(*State)(&state)
copies the content at &state
to the s address (after casting *rawState
to *State
). But if it is that way, wouldn't it be more efficient to just do s = (*State)(&state)
instead of copying and *state
being collected by GC? Or could it lead to side-effects changing the value of s / or other reasons for doing it this way? Thanks!
complete function from [0]:
func (s *State) UnmarshalJSON(b []byte) error {
type rawState State
var state rawState
dec := json.NewDecoder(bytes.NewReader(b))
if s.useJSONNumber {
dec.UseNumber()
}
err := dec.Decode(&state)
if err != nil {
return err
}
*s = *(*State)(&state)
return s.Validate()}
答案1
得分: 1
这个任务:
*s = *(*State)(&state)
确实复制了指向的值。这是必需的,因为s
是一个局部变量,将任何东西赋给s
本身在函数返回后将没有任何效果。
这个语句的意图是将某个东西赋给s
指向的位置,这就是上面的赋值语句所做的事情。
使用rawState
的目的是创建一个没有UnmarshalJSON()
方法的新类型,因此将*rawState
传递给json.Unmarshal()
不会导致堆栈溢出。
参考链接:https://stackoverflow.com/questions/43176625/call-json-unmarshal-inside-unmarshaljson-function-without-causing-stack-overflow/43178272#43178272
英文:
The assignment:
*s = *(*State)(&state)
Does copy the pointed value. This is required because s
is a local variable, assigning anything to s
itself will have no effect once the function returns.
The intention is to assign something where s
points to, and that is what the above assignment statement does.
The goal of using rawState
is to create a new type which does not have the UnmarshalJSON()
method, so passing *rawState
to json.Unmarshal()
will not cause a stack overflow.
答案2
得分: 0
s
是一个指针,假设指向内存中的位置x
。
&state
是另一个指针,指向内存位置y
。
函数UnmarshalJSON
被调用时,使用指向内存位置x
的指针。
如果你执行以下操作:
*s = *(*State)(&state)
这意味着:
取指向y
(&state
)的指针,将其转换为正确的指针类型(*State
),然后转到内存位置y
(在=
之后的*
),然后将该值(=
)复制到另一个内存位置x
(*s
)。
另一方面,如果你执行:s = (*State)(&state)
这意味着:
取指向y
(&state
)的指针,将其转换为正确的指针类型(*State
),将该指针(=
)复制给接收器(s
)。调用此函数的任何位置指向的内存位置x
保持不变。
此外,当方法被调用时,指针本身作为s
传递给UnmarshalJSON
,它是从调用它的位置复制的指针。UnmarshalJSON
内部的s
是类型为*State
的值,它在UnmarshalJSON
之外不存在。因此,这个赋值在UnmarshalJSON
之外是没有意义的。
英文:
s
is a pointer lets say pointing to location x
in memory.
&state
is another pointer at memory location y
.
the function UnmarshalJSON
is called with pointer pointing to memory location x
.
if you do:
*s = *(*State)(&state)
this means:
take pointer to y
(&state
), convert it to the correct pointer type(*State
), then go to memory location y
(* at the beginning after =
) and then copy the value(=
), to this other memory location x
(*s
).
if you, on the other hand, do: s = (*State)(&state)
this means:
take pointer to y
(&state
), convert it to correct pointer type(*State
), copy that pointer(=
) to receiver (s
). The memory location x
being pointed to by whatever called this function, remains unchanged.
Also when the method is called the pointer itself, received by UnmarshalJSON
as s
, is a copy of the pointer at the position it's called from. This s
inside UnmarshalJSON
is a value of type *State
that does not exist beyond UnmarshalJSON
. This assignment will hence be meaningless beyond UnmarshalJSON
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论