使辅助函数通用

时间:2017-08-01 15:14:28

标签: function generics go

我创建了一个小辅助函数,将大量项目拆分为最小大小为public partial class ApriAllegato : System.Web.UI.Page { protected void Page_Load(object sender, System.EventArgs e) { string pathCompleto = Request.QueryString["pathCompleto"]; string filename = ''; //Get the file name from the path Response.Clear(); Response.ClearContent(); Response.ClearHeaders(); if (pathCompleto.EndsWith(".pdf")) { Response.ContentType = "application/pdf; name=" + filename; } else { Response.ContentType = "application/octet-stream; name=" + filename; } Response.AddHeader("content-transfer-encoding", "binary"); Response.AppendHeader("Content-Disposition", "attachment;filename=" + filename); Response.ContentEncoding = System.Text.Encoding.GetEncoding(1251); Response.WriteFile(pathCompleto); Response.End(); } } 的较小数组。

n

Golang Playground的工作示例 在程序中我有几种不同类型的数组,我想分开。我尝试将其转换为使用func toPackages(e []int, n int) [][]int { var p [][]int packets := int(math.Ceil(float64(len(e)) / float64(n))) for i := 0; i < packets; i++ { start := i * n end := n * (i + 1) if len(e) < end { end = len(e) } p = append(p, e[start:end]) } return p } 的接口。

2 个答案:

答案 0 :(得分:3)

制作一个通用函数来处理这个问题非常困难。您经常会花费尽可能多的代码将[]int转换为[]interface{}并返回,因为它只是复制代码段。我确实有一个更好的方法来做到这一点:

playground link

func splitInts(src []int, n int) (p [][]int){
    for len(src) > n{
        p = append(p,src[:n])
        src = src[n:]
    }
    if(len(src) > 0){
        p = append(p,src)
    }
    return p
}

由于类型的原因,函数中的任何内容都不会更改,因此可以轻松复制到:

func splitStrings(src []string, n int) (p [][]string){
    for len(src) > n{
        p = append(p,src[:n])
        src = src[n:]
    }
    if(len(src) > 0){
        p = append(p,src)
    }
    return p
}

仅改变第一行。

答案 1 :(得分:0)

通常,只为每种类型的函数编写函数是个好主意。这也是一个速度问题:如果你使用反射来编写泛型函数,它将不会那么快。

如果你仍然想要一个通用函数,那就是:

func genToPackages(e interface{}, n int) interface{} {
    t := reflect.TypeOf(e)
    if t.Kind() != reflect.Slice {
        log.Println("e has to be a slice")
    }
    v := reflect.ValueOf(e)

    packets := int(math.Ceil(float64(v.Len()) / float64(n)))
    p := reflect.MakeSlice(reflect.SliceOf(t), packets, packets)
    for i := 0; i < packets; i++ {
        s := reflect.MakeSlice(t, n, n)
        start := i * n
        for j := 0; j < n; j++ {
            s.Index(j).Set(v.Index(j+start))
        }

        p.Index(i).Set(s)
    }

    return p.Interface()
}

您必须将结果转换为您期望的类型。例如:

res := genToPackages([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 5).([][]int)