只有在满足特定条件的情况下才创建一个GO结构体。

huangapple go评论76阅读模式
英文:

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 &amp; 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&#39;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&#39;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{}
    }

额外提示:_未来的你_会感谢你将其重构为一对语句,确定是否需要ab或两者,并将复合if语句简化为两个_单独的_语句,分别初始化ab

    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是否被需要的问题与在需要时初始化ab的过程分离开来。

注意:根据你发布的代码,无法更具体地表达condition 2是什么条件。

英文:

You have two problems in your code:

  1. your variables are declared within an enclosing scope, making them unreachable from outside that scope (the if/else clauses)
  2. 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 = &amp;MyStruct{}
    } else if b == nil {
        cond = 1
        B_mystruct_obj = &amp;MyStruct{}
    } else {
        cond = 2
        A_mystruct_obj = &amp;MyStruct{}
        B_mystruct_obj = &amp;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 = &amp;MyStruct{}
    }
    if breq {
        B_mystruct_obj = &amp;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.

huangapple
  • 本文由 发表于 2023年4月3日 01:56:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75913707.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定