大佬教程收集整理的这篇文章主要介绍了Go 中的广义参数,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我不明白在下一个问题中我应该选择什么方法: 我有一个接收切片参数的方法。我希望它可以接受不同类型的切片。目前,我不认为消费者将来使用我的方法会如何更好:他们会使用某种类型还是另一种类型。 我不确定,但我考虑下一个解决方案:
func getnamesString(users []interface{}){
str := ""
switch users[0].(typE){
case User:
for i,us:= range users{
str += us.username + "|"
}
case String:
for i,name:= range users{
str += name + "|"
}
....
}
}
在像 Ruby 这样的动态语言中,这是正常的做法。据我所知,在 c# 或 java 中,它用于此任务的泛型。但是我们应该在 Go 中做什么?我觉得我的方法是错误的,我必须分别为每种类型或仅为一种类型制定方法,并强制客户将他们的输入转换为这种类型(例如字符串)。 非常感谢!
您可以为此使用接口。
package main
import (
"bytes"
"fmt"
)
func main() {
namesString := getNamesString([]User{
UserString("Name 1"),UserNamed{name: "Name 2"},})
fmt.Printf(namesString)
}
// Interface that you struct need to match
type User interface {
GetName() String
}
func getNamesString(users []User) String {
var buffer bytes.buffer
for _,user := range users {
buffer.WriteString(user.GetName())
buffer.WriteRune('|')
}
return buffer.String()
}
// A simple wrapper around String to implement your interface
type UserString String
func (u UserString) GetName() String {
return String(u)
}
// Another struct
type UserNamed struct {
Name String
}
func (u UserNamed) GetName() String {
return u.Name
}
完整示例,包含 String
和 struct
如果您不想按照 XciD 的答案中的建议定义接口,您可以更改 getNamesString 以接受某个集合中的元素数 N,以及一个返回该集合中第 N 个元素的字符串表示形式的函数。然后,您可以使用特定类型的闭包调用它:
package main
type User struct {
Username String
}
func main() {
users := []User{}
getNamesString(len(users),func(i int) String { return users[i].Username })
Strings := []String{}
getNamesString(len(Strings),func(i int) String { return Strings[i] })
}
func getNamesString(len int,toString func(int) String) {
str := ""
for i := 0; i < len; i++ {
str += toString(i) + "|"
}
}
这种方法本质上就是 the sort package 的工作原理。请注意,getNamesString 现在可用于支持按索引访问的所有数据结构,而不仅仅是切片。
,简短的回答 - 你现在拥有的最好。
在这种情况下,您可以使用反射,但正如我所见,您始终需要了解类型。如果你认为“我不需要知道类型”,那么这段代码可以很好地使用反射来完成。一定要注意反思需要时间。
在您的情况下,传入参数是 []User
或 []String
,因为您只需查看元素 0 的类型即可检查它们中的哪一个。所以在您的情况下,您是编写两个不同的函数可能会更好,因为调用者肯定知道切片的类型并且可以决定调用哪个函数。但是,如果您仍然希望创建一个可以同时执行这两个功能的函数,您可能应该将 interface{}
作为参数类型,然后检查它是否是切片是或否,因为 []User
或 {{1 }} 满足您似乎假设的 []String
类型。第一个是用户(或字符串)的切片,第二个是未定义的任何东西的切片,它们是不同的概念。
[]interface{}
但我相信这是更好的解决方案:
import (
"internal/reflectlite"
)
func getNamesString(users interface{}){
if reflectlite.ValueOf(users).Kind() != reflectlite.Slice {
return // Probably returning an error would be better.
}
...
}
,
尝试 Go 泛型
func getNamesString(users [T]){
//code ommited for simplicity
....
}
以上是大佬教程为你收集整理的Go 中的广义参数全部内容,希望文章能够帮你解决Go 中的广义参数所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。