Golang有类似C++的decltype吗?

4

C++有decltype(expr)。你可以声明一个类型与其他表达式相同的对象。例如:decltype('c') a[4]将声明一个包含4个字符的数组。这只是一个玩具示例,但这个特性非常有用。这里是一个用于UDP服务器的Go代码:

conn, err := net.ListenUDP("udp", udp_addr)
...
defer conn.Close()
...
_, err = conn.WriteToUDP(data, addr)

重要的是我知道如何使用函数的结果类型(在这种情况下,使用连接,即ListenUDP的结果),但我不知道这个类型是什么。由于 Go 有类型推断,因此我无需知道。但是如果我想创建 5 个连接,那么我希望有一个包含 5 个“ListenUDP的结果”的数组。我做不到。最接近的我所得到的是:
ret_type := reflect.TypeOf(net.DialUDP)
first_param_type := reflect.TypeOf(ret_type.Out(0))
my_arr := reflect.ArrayOf(4, first_param_type)
my_arr[0] = nil

但是最后一行不起作用。有没有一种方法可以在Go中实现它?
1个回答

3

Go没有像C++的decltype那样的编译时等价物。

但是,Go是一种静态类型语言:即使在短变量声明的情况下存在类型推断,类型也在编译时得以知晓。 net.ListenUDP() 的结果类型在源代码中不可见,但是您可以轻松地查找到它,例如,用鼠标悬停2秒钟,您的IDE将显示其签名。或者查看在线文档。或在终端中运行go doc net.ListenUDP

net.ListenUDP()的签名为:

func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error)

因此,用于保存5个返回连接的数组类型是[5]*net.UDPConn。另外请注意,在Go中使用切片(slices)代替数组(arrays)更好、更容易。
因此,我建议使用切片类型[]*net.UDPConn。如果需要一个包含5个连接的切片,可以使用内置函数make()创建,如下所示:make([]*net.UDPConn, 5)
如果确实需要在运行时动态执行此操作,则可以使用反射(reflection)。它可能看起来像这样:
funcType := reflect.TypeOf(net.ListenUDP)
resultType := funcType.Out(0)
arrType := reflect.ArrayOf(4, resultType)
arrValue := reflect.New(arrType).Elem()

conn := &net.UDPConn{}
arrValue.Index(0).Set(reflect.ValueOf(conn))

fmt.Println(arrValue)

这将输出(在Go Playground上尝试一下):
[0xc00000e058 <nil> <nil> <nil>]

相关内容请查看:在Go中声明类型相同的多个变量


我明白了,谢谢!但是你可以很容易地查找它,例如,将鼠标悬停在其上需要2秒钟,您的IDE将显示签名。或者在线检查。或在终端中运行go doc net.ListenUDP。我的问题实际上不是“我不知道ListenUDP的返回类型”,而是我不知道go doc <something>,这很有用。另外,我没有尝试过许多IDE(针对Go),只有VSCode。依我之见,官方扩展有些烦人,所以我关闭了它,并且只有默认的语法高亮。 - Stefanos Baziotis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接