程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Go 中的广义参数大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决Go 中的广义参数?

开发过程中遇到Go 中的广义参数的问题如何解决?下面主要结合日常开发的经验,给出你关于Go 中的广义参数的解决方法建议,希望对你解决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
}

完整示例,包含 Stringstruct

,

如果您不想按照 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,请注明来意。
标签: