gpt4 book ai didi

go - 我如何使用接口(interface)定义安全划分并反射(reflect)?

转载 作者:数据小太阳 更新时间:2023-10-29 03:40:19 26 4
gpt4 key购买 nike

我想定义一个安全分区,例如:

func safeDivide(a, b interface{}) interface{} {
if b == 0 {
return 0
}
return a / b
}

很明显,这个功能是行不通的。我们不能划分界面。一种解决方案是判断输入的类型并进行除法。

switch reflect.ValueOf(x).Kind() {
case reflect.Int:
// balabala...

虽然看起来很多余,但我必须处理每一个案子。

那么我是否可以使用反射来保证输入的类型?我试过 reflect.TypeOf() 但失败了。

顺便说一句,我注意到了这一点:

a := uint32(0)
ifZero(a) // outputs "no"

func ifZero(a interface{}) {
if a == 0 {
log.Println("yes")
return
}
log.Println("no")
}

这意味着 golang 本身无法处理类型问题,对吧?

最佳答案

如您在 a comment 中所述,现在你知道为什么(有些)人想要在 Go 中使用泛型了。 :-)

对于这种特殊情况,您最好只编写一个 safeDivideInt 函数:

// a/b, but 0 if b == 0
func safeDivideInt(a, b int64) int64 {
if b == 0 {
return 0
}
return a / b
}

和一个类似的 safeDivideUint 函数(使用 uint64)...并且,如果需要,1 safeDivideFloat 函数,例如:

func safeDivideFloat(a, b float64) float64 {
// decide if you want 0/0 handled differently
// decide if you want to check for b being Inf or NaN
// etc.
if b == 0 {
return 0
}
return a / b
}

如果需要,然后再进行复杂的处理。

但是:没有简单的方法让 Go 编译器为您调用一个或另一个。您可以按照您的方式编写基于接口(interface)的函数,然后对各种参数进行类型切换,但它会变得很长,因为您必须处理所有可能的组合。无论你如何减少它,组合效应都是痛苦的。使用 reflect 及其 type-kind 接口(interface)在这里没有帮助,因为您仍然有五种 int 类型,五种 uint 类型(如果您包括uintptr),两种 float 类型,以及两种 complex 类型。 (我不清楚在除法函数中允许 UintptrUnsafePointer Kind 是否有任何意义。)

然而,根据上下文定义您自己的界面可能更有意义。 Here's a working toy example on the Go Playground .我没有费心输入 Uint 和 Complex 类型。


1请注意,运行时 1.0/0.0 是 +InfGo specification说:

The result of a floating-point or complex division by zero is not specified beyond the IEEE-754 standard; whether a run-time panic occurs is implementation-specific.

但是 IEEE-754 默认情况下调用 Inf 和 NaN 结果,异常(exception)是可选的,所以我认为这意味着 Go 中的默认值不会引发异常,也意味着“没有 panic ”。参见,例如 this Wikipedia entry我在这里引用了一点:

Arithmetic exceptions are (by default) required to be recorded in "sticky" status flag bits. ... By default, an operation always returns a result according to specification without interrupting computation. For instance, 1/0 returns +∞, while also setting the divide-by-zero flag bit (this default of ∞ is designed so as to often return a finite result when used in subsequent operations and so be safely ignored).

关于go - 我如何使用接口(interface)定义安全划分并反射(reflect)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57441284/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com