如何在Go语言中创建一个可以接受多种类型的类型

r3i60tvu  于 2023-03-06  发布在  Go
关注(0)|答案(1)|浏览(409)

如何创建自己的类型来接受bool、string或int,而不使用any接口?
目前,如果你想支持多个类型,比如说作为一个HashMap的值,你可以做如下的事情:

data = make(map[string]any)
data["bool"] = true
data["string"] = "string"
data["int"] = 3

然后你可以把它传递给如下函数:

func doStuff(data map[string]any) {
  ...
}

我尝试了以下方法:

type CustomType interface {
    ~int | ~bool | ~string
}

data = make(map[string]CustomType)

但是Go语言会抱怨我不能在泛型函数的类型约束之外使用它。

u91tlkcl

u91tlkcl1#

这听起来像是你在寻找一个“求和类型”,Go语言并没有这样的类型,至少在正确的意义上没有,但是你有几个不同的选择来做类似的事情:
首先:创建一个结构体,其中包含所有需要的类型作为字段。

type Sum struct {
  I int
  B bool
  S string
}

这在make(map[string]Sum)这样的类型中非常好用,但是任何时候你想从这种类型中得到底层的int、bool或string,你必须显式地请求你想要的类型,你也没有任何内置的机制来跟踪你在给定的值中有什么类型的东西,你可以添加逻辑来跟踪它,看起来像这样:

type Sum struct {
  i int
  isInt bool

  b bool
  isBool bool

  s string
  isString bool
}

func Int(i int) Sum {
  return Sum{i: i, isInt: true}
}

func (s Sum) IsInt() bool {
  return s.IsInt
}

func (s Sum) Int() int {
  if !s.isInt {
    panic("not an int")
  }
  return s.i
}

// Similar Bool() and String() functions.

从理论上讲,如果您真的 * 真的*真的需要这段代码的每一点性能,那么您可以使用一些技巧,使它像this question中描述的C中的联合类型一样工作。
第二,你可以做类似的事情,但是要使用接口。This post展示了它的工作原理,它的优点是可以使用Go语言内置的类型转换语法来查找你所拥有的值。
第三:继续使用any,它更简单,已经内置,并且相当有效,使用any的唯一缺点是,与其他选项不同,它可能构造具有意外类型的值(例如,您可以将float传递到接受any的对象中,但您不能从float创建Sum值)。

相关问题