将类型断言移动到返回任意类型的函数内部。

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

Move type assertion within function that returns any

问题

我有一个通用的Go函数示例:

package main

func read(address uint16) any {

	switch address {
	case 1:
		return float64(0.5)
	case 2:
		return int(8)
	default:
		return "Hello"
	}

}

func main() {
	v1 := read(1)
	v2 := read(2)

	v1 = v1 / 2.5
	v2 = v2 * 4
}

由于缺少类型断言,上述代码会失败。请参考go.dev/play上的代码。

为了避免这个问题,可以按照Go泛型教程中的方法使用类型断言:

v1 = v1.(float64) / 2.5
v2 = v2.(int) * 4

以正确地提供类型。然而,我想创建一个通用的方法来读取传感器值。用户和编译器都知道,如果调用read(1),则返回一个float64,如果调用read(2),则始终返回一个整数。

总之,有没有办法在read()函数之外避免使用类型断言语法?

我能想到的唯一不太好的方法是创建不同的readInt()readFloat64()函数,但我更愿意保留一个通用的读取方法。

英文:

I have the following example of generic Go function:

package main

func read(address uint16) any {

	switch address {
	case 1:
		return float64(0.5)
	case 2:
		return int(8)
	default:
		return "Hello"
	}

}

func main() {
	v1 := read(1)
	v2 := read(2)

	v1 = v1 / 2.5
	v2 = v2 * 4
}

which fails because of missing type assertion. See code on go.dev/play.

In order to avoid this, I may use type assertion as per Go tutorial on generics:

v1 = v1.(float64) / 2.5
v2 = v2.(int) * 4

to correctly provide the type. However, I would like to create a generic method to read sensor values. Both the user and the compiler know that if read(1) is called then a float64 is returned, the same goes if read(2) is called which always returns an integer.

Bottom line: is there any way I can avoid the type-assertion syntax outside the function read()?

The only ugly way I can think of is to have different read functions like readInt() and readFloat64(), but I'd rather keep a generic method for reading.

答案1

得分: 2

是的,可以使用泛型将类型断言移到函数内部。

func read[T any](address uint16) T {
    var result any
    switch address {
    case 1:
        result = float64(0.5)
    case 2:
        result = int(8)
    default:
        result = "Hello"
    }
    return result.(T)
}

func main() {
    v1 := read[float64](1)
    v2 := read[int](2)

    v1 = v1 / 2.5
    v2 = v2 * 4
    fmt.Println(v1, v2)
}

在上面的代码中,我们使用了泛型类型参数 T 来表示要读取的值的类型。在 read 函数内部,我们根据给定的地址选择要返回的值,并将其存储在 result 变量中。然后,我们使用类型断言 result.(T)result 转换为 T 类型并返回。

main 函数中,我们使用 read 函数来读取一个 float64 类型的值和一个 int 类型的值,并对它们进行一些操作。最后,我们打印出结果。

英文:

> is there any way I can avoid the type-assertion syntax outside the function read()?

Yes, use generics to move the type assertion inside of the function.

func read[T any](address uint16) T {
	var result any
	switch address {
	case 1:
		result = float64(0.5)
	case 2:
		result = int(8)
	default:
		result = "Hello"
	}
	return result.(T)
}

func main() {
	v1 := read[float64](1)
	v2 := read[int](2)

	v1 = v1 / 2.5
	v2 = v2 * 4
	fmt.Println(v1, v2)
}

huangapple
  • 本文由 发表于 2023年5月16日 21:01:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76263320.html
匿名

发表评论

匿名网友

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

确定