英文:
Create a GO struct only if a certain condition is satisfied
问题
我的GO代码片段如下:
type MyStruct struct {
a int
}
if a == nil {
cond = 0
var A_mystruct_obj MyStruct // 只有在满足这个条件时才创建 A_mystruct_obj 对象
} else if b == nil {
cond = 1
var B_mystruct_obj MyStruct // 只有在满足这个条件时才创建 B_mystruct_obj 对象
} else {
cond = 2 // 如果满足这个条件,则同时创建上述两个结构对象 A_mystruct_obj 和 B_mystruct_obj。
// 在 else 中再次声明以下内容是否是有效的GO代码?
var A_mystruct_obj MyStruct
var B_mystruct_obj MyStruct
}
我来自C++背景。在C++中,这个问题很简单。GO语言中是否有动态内存分配?我该如何在GO中实现这个?
在else中再次声明这两个变量是有效的GO代码吗?
var A_mystruct_obj MyStruct
var B_mystruct_obj MyStruct
还是我需要在这里使用某种形式的运行时多态性?
**更新:**
我尝试了这种方式,但它并没有像预期的那样编译通过。
[这是我尝试的代码](https://go.dev/play/p/ioQ81aeXGjN)
**再次更新:**
我尝试了这个方法,似乎可以工作。这样可以吗?
[这是我尝试的代码](https://go.dev/play/p/R_ywzmkgRpS)
<details>
<summary>英文:</summary>
My GO code snippet is as follows:
type MyStruct struct {
a int
}
if a == nil {
cond = 0
var A_mystruct_obj MyStruct // If this condition is satified then ONLY create this A_mystruct_obj obj
} else if b == nil {
cond = 1
var B_mystruct_obj MyStruct // If this condition is satified then ONLY create this B_mystruct_obj obj
} else {
cond = 2 // // If this condition is satified then create BOTH the above structure objects A_mystruct_obj & B_mystruct_obj.
// Is having the below declaration again in else a valid GO code ?
var A_mystruct_obj MyStruct
var B_mystruct_obj MyStruct
}
I'm from a C++ background. This would have been simple in C++. Do we have dynamic memory allocation in GO. And how do I achieve this in GO ?
Is having the 2 declaration again in else a valid GO code ?
var A_mystruct_obj MyStruct
var B_mystruct_obj MyStruct
Or do I need to have some sort of run time polymorphism here.
**Updated:**
I tried doing this way, but it didn't even compile as expected.
https://go.dev/play/p/ioQ81aeXGjN
**Updated Again**
I tried this and it seems to work. Is this fine ?
https://go.dev/play/p/R_ywzmkgRpS
</details>
# 答案1
**得分**: 1
你的代码有两个问题:
1. 变量在封闭作用域中声明,使得在该作用域外部无法访问(`if`/`else`子句)
2. 变量被声明为值类型
第二个问题是当你解决第一个问题时出现的,即将变量声明移到`if`子句的作用域之外,以使其可以在`if`语句后的代码中访问:
```golang
var A_mystruct_obj MyStruct
var B_mystruct_obj MyStruct
if a == nil {
cond = 0
// 初始化 A_mystruct
} else if b == nil {
cond = 1
// 初始化 B_mystruct
} else {
cond = 2
// 初始化 A_mystruct 和 B_mystruct
}
现在两个变量都被声明了,但是无论if
语句中的哪个子句被执行,这两个变量都会被初始化为新分配的MyStruct
。
为了解决这个问题,将变量改为指针,并在if
语句的相应分支中分配所需的值:
var A_mystruct_obj *MyStruct
var B_mystruct_obj *MyStruct
if a == nil {
cond = 0
A_mystruct_obj = &MyStruct{}
} else if b == nil {
cond = 1
B_mystruct_obj = &MyStruct{}
} else {
cond = 2
A_mystruct_obj = &MyStruct{}
B_mystruct_obj = &MyStruct{}
}
额外提示:_未来的你_会感谢你将其重构为一对语句,确定是否需要a
或b
或两者,并将复合if
语句简化为两个_单独的_语句,分别初始化a
或b
:
var A_mystruct_obj *MyStruct
var B_mystruct_obj *MyStruct
areq := a == nil || (..condition 2..)
breq := b == nil || (..condition 2..)
if areq {
A_mystruct_obj = &MyStruct{}
}
if breq {
B_mystruct_obj = &MyStruct{}
}
这样做的目的是避免逻辑重复(DRY原则:不要重复自己)和关注点分离。即将a
和/或b
是否被需要的问题与在需要时初始化a
和b
的过程分离开来。
注意:根据你发布的代码,无法更具体地表达condition 2
是什么条件。
英文:
You have two problems in your code:
- your variables are declared within an enclosing scope, making them unreachable from outside that scope (the
if
/else
clauses) - your variables are declared as values
The second problem arises when you address the first, i.e by moving your variable declarations outside of the if
clause scopes, to make them accessible to code following the if
statement:
var A_mystruct_obj MyStruct
var B_mystruct_obj MyStruct
if a == nil {
cond = 0
// initialise A_mystruct
} else if b == nil {
cond = 1
// initialise B_mystruct
} else {
cond = 2
// initialise A_mystruct and B_mystruct
}
Now both variables are declared but also both variables are initialised with a newly allocated MyStruct
, regardless of which clause in the if
statement is reached.
To solve that problem, change the variables to pointers and allocate the values required in the corresponding branch of the if
statement:
var A_mystruct_obj *MyStruct
var B_mystruct_obj *MyStruct
if a == nil {
cond = 0
A_mystruct_obj = &MyStruct{}
} else if b == nil {
cond = 1
B_mystruct_obj = &MyStruct{}
} else {
cond = 2
A_mystruct_obj = &MyStruct{}
B_mystruct_obj = &MyStruct{}
}
Bonus tip: Future You will thank you for refactoring this to a pair of statements that determine whether a
is required or b
or both and then simplifying your compound if
statement as two separate statements that initialise an a
or b
respectively:
var A_mystruct_obj *MyStruct
var B_mystruct_obj *MyStruct
areq := a == nil || (..condition 2..)
breq := b == nil || (..condition 2..)
if areq {
A_mystruct_obj = &MyStruct{}
}
if breq {
B_mystruct_obj = &MyStruct{}
}
The intent being to avoid repetition of logic (the DRY principle: Don't Repeat Yourself) and separation of concerns. i.e. separating the question of whether a
and/or b
are required from the process of initialising a
and b
when they are required.
NOTE: It isn't possible to be more specific as to how to express condition 2
as it is not clear from your posted code what that condition is.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论