3 回答
TA贡献1893条经验 获得超10个赞
有没有办法将允许的类型减少到 [空接口] 的特定类型列表?
在编译时,没有。
但是,您可以选择在运行时使用限制。当有其他选择时,应该避免这种情况,因为它不能提供足够的安全性。
这是在标准库中的许多地方完成的,例如 json marshaler,它需要一个指针作为目标。
TA贡献1871条经验 获得超8个赞
您不能在编译时以您想要的方式强制使用一组具体类型。
您可以做的是使用接口。列出您期望从实现中获得的接口中的方法。那么具体的运行时类型是什么就无关紧要了。您仅通过接口与值交互,这在编译时保证它是由传递的值实现的。
例如,如果您希望该值提供一个int32值,请使用此接口:
type HasInt32 interface {
Int32() int32
}
func f(i HasInt32) {
fmt.Println("int32 value:", i.Int32())
}
int32传递的值是否具有或float64作为其基础类型,或者它是任何其他复杂类型都无关紧要。你需要一个int32,这就是你得到的。实现者负责如何产生该值。
例如:
type MyInt32 int32
func (m MyInt32) Int32() int32 { return int32(m) }
type MyStruct struct {
i int64
}
func (m MyStruct) Int32() int32 { return int32(m.i) }
测试它:
var m MyInt32 = 1
f(m)
var s MyStruct = MyStruct{i: 2}
f(s)
哪些输出(在Go Playground上尝试):
int32 value: 1
int32 value: 2
TA贡献1828条经验 获得超6个赞
有没有办法将允许的类型减少到特定的类型列表?
是的,从 Go 1.18 开始,使用带有类型元素的接口。但是这样的接口只能作为类型参数的约束。在规范的草案版本中,接口类型下提到了这一点:
包含非接口类型、~T 形式的术语或联合的接口只能用作类型约束,或用作用作约束的其他接口的元素。它们不能是值或变量的类型,也不能是其他非接口类型的组件。
简而言之,在接口中,除了方法签名和其他嵌入式接口之外,您现在可以添加类型元素。这定义了一个类型约束,即“相应类型参数的允许类型参数集”。
尤其:
接口约束可以指定一个或多个类型元素。它将类型参数限制为指定的类型。您可以将多个类型元素指定为联合(更多信息:Go Generics - Unions)
type MyNumber interface {
float32 | float64 | uint | int
}
您可以使用标记~来指定近似元素,即基础类型为的所有类型的集合T(更多信息:Go 中新标记〜的含义是什么(近似元素)?)。这些也可以是工会的一部分。
type MyNumber interface {
~float32 | ~float64 | ~uint | ~int
}
您仍然可以在这样的接口中指定方法签名。它将类型参数限制为也实现接口的那些类型的集合:
// set of types with underlying int that also implement `String() string`
type MyNumber interface {
~int
String() string
}
作为上述推论,如果接口指定了非近似的预声明类型和方法,则没有类型会满足接口(因为您不能在预声明类型上声明方法)
// empty type set
type MyNumber interface {
int
String() string
}
如前所述,您仅将其用作类型参数约束,您将无法在类型切换、声明变量等中使用它:
func foo[T MyNumber](v T) {
// ...
}
- 3 回答
- 0 关注
- 177 浏览
添加回答
举报