在全局范围内初始化一个结构体,其类型取决于布尔值。

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

Initialize struct with global scope where type depends on boolean

问题

我最近开始使用Golang,并遇到了一个问题:

我有两个结构体,humanalien,它们都基于creature结构体。我想根据if语句中的isAlien布尔值的值来初始化其中一个。

在if块中使用human := human{}或等效的alien初始化方式,实例在if语句外部是不可访问的。

另一方面,通常的解决方案是在if语句之前声明变量的类型和名称,并在if语句内部初始化变量,但这种方法不起作用,因为这两个类型是不同的:

var h human //在这里使用human还是alien?
if isAlien {
  h = alien{} //错误:类型不兼容
} else {
 h = human{}
}
//当在声明中将human替换为alien时,情况相同

我知道我可以在if语句之前声明两种类型,但这个解决方案对我来说不够优雅。

这里有什么明显的解决方案我忽略了吗?

英文:

I started using Golang recently and stumbled across a problem:

I have two structs, human and alien, which are both based on the creature struct. I want to initialize one of them based on the value of the isAlien boolean inside of an if-statement.

Using the human := human{} notation or the alien equivalent inside the if blocks to initialize, the instances aren't accessible from outside of the if-statement.

On the other hand, the usual solution of declaring the type and the name of the variable before the if-statement and initializing the variable inside the if-statement doesn't work, because there two are different types:

var h human //use human or alien here?
if isAlien {
  h = alien{} //Error: incompatible types
} else {
 h = human{}
}
//same when swapping human with alien at the declaration

I know that I could just declare both types before the if-statement but that solution doesn't seem elegant to me.

Is there some obvious solution that I'm missing here?

答案1

得分: 2

正如你所指出的,这个问题可以通过以下语句清晰地表示:

var h human // 在这里使用 human 还是 alien?

如果你计划在创建对象后使用变量 h,那么 h 的类型必须能够接受 humanalien 作为值。

在 Go 语言中,可以通过使用一个 interface 来实现这一点,这个 interface 可以被 alienhuman 都满足。

所以你应该声明一个类似这样的 interface

type subject interface {
    // 你计划在之后使用 "h" 的所有函数都应该列在这里
    // "human" 和 "alien" 都必须实现这些函数
}

然后:

var h subject

就可以解决问题了。

英文:

As you noted, the problem is clearly represented by this statement:

var h human //use human or alien here?

If you plan to use that h variable there after creating the objects, then the type of h must be one that can accept either a human or alien as a value.

The way to do this in Go is by using an ìnterface that both alien and human can fulfil.

So you should declare an interface like:

type subject interface {
    // you should list all functions that you plan to use on "h" afterwards
    // both "human" and "alien" must implement those functions 
}

Then:

var h subject

Will do the trick.

答案2

得分: 1

所以,我要冒昧地说,你可能以错误的方式思考了这个问题。

看到你的示例后,我首先想到的问题是:这个函数的返回类型是什么?换句话说,你需要h是什么样的签名?如果alien有一个嵌入的结构体creature(这似乎是你试图遵循的继承模式),并且在声明hcreature后从函数中返回一个human,那么使用该函数的任何东西只会知道它正在处理一个creature,所以一开始将其声明为humanalien是没有意义的。

我怀疑你真正想做的是摆脱具体的结构体,而是使用接口。在这种情况下,你会有一个creature接口,humanalien都会满足creature接口。你不一定知道你正在处理哪一个,但你可以可靠地调用creature的方法,适当的humanalien实现将被调用。

英文:

So, I'm going to go out on a limb and say you're probably thinking about this the wrong way.

The first question that occurs to me looking at your example is: what's the return type of this function? In other words, what signature do you need h to be? If alien has an embedded struct creature (which seems to be the inheritance pattern you're trying to follow), and you return a human from your function after declaring h to be a creature, anything that consumes your function will only know that it's dealing with a creature, so there's no point in declaring it a human or an alien in the first place.

I suspect that what you really want to be doing is moving away from concrete structs here and instead using interfaces. In that world, you'd have a creature interface, and both human and alien would satisfy the creature interface. You wouldn't necessarily know which one you were dealing with downstream, but you'd be able to reliably call creature methods and the appropriate human or alien implementation would be invoked.

huangapple
  • 本文由 发表于 2018年5月27日 03:11:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/50546218.html
匿名

发表评论

匿名网友

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

确定