golang 泛型

小幸运Q · · 3840 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

https://draveness.me/whys-the-design-go-generics/


泛型困境

泛型困境使我们必须在开发效率、编译速度和运行速度三者中选择两个;

目前社区中的 Go 语言方案都是有缺陷的,而 Go 团队认为泛型的支持不够紧急;

对于泛型编程的通常有以下三种处理方式:

1.(C语言)放弃泛型。这样苦了程序员,但是也降低了语言的复杂性。

2.(C++语言)编译期特化或者大量地展开代码。这样苦了编译器。编绎器生成一堆代码,而大部分是无用的,需要一个很好的链接器去清除重复的副本。为每一个类型生成一份代码,也许这样会让代码执行更高效,但是程序是一个整体,这样会造成对cpu的cache不友好。我曾听说一个简单的库修正和移除了模板后,text段(即动态链接库的文件格式中的text段)的大小从M级降到10K。

3.(Java语言)隐式地把所有东西装箱。这样苦了程序,执行起来会变慢

对比C语言的手写,C++语言的编译器生成,Java代码量最少,但是时空上最低效,无论是从时间还是空间来说。因为所有的操作都要隐式地装箱和拆箱。一个byte的vector容器(Vector<Byte>)所占的空间比远超一个byte。想要隐藏装箱和拆箱会让类型系统变复杂。从另一个方面来说,这个也许是指令cache友好的,因为它把一个byte的vector(Vector<Byte>)可以分开来写每一个byte。

package sort

func Float64s(a []float64)

func Strings(a []string)

func Ints(a []int)

上述函数都是 sort 包提供的,它们的功能非常相似,底层的实现也使用了近乎相同的逻辑,但是由于传入类型的不同却需要对外提供多个函数。Java 的泛型就解决了这个问题

public class ArraySortViaComparable {

    public <E extends Comparable> void insertionSort(E[] a) {

        for (int i = 1; i < a.length; i = i + 1) {

            Comparable itemToInsert = a[i];

            int j = i;

            while (j != 0 && greaterThan(a[j-1], itemToInsert)) {

                a[j] = a[j-1]

                j = j - 1

            };

            a[j] = itemToInsert;

        }

    }

private static boolean greaterThan(E left, Object right) { 
    return left.compareTo(right) == 1; }
}

这段 Java 代码使用泛型数组作为参数实现了通用的数组排序逻辑,任意类型只要实现了 Comparable 接口,insertionSort 函数就能排序由该对象组成的数组。使用泛型能够减少重复的代码和逻辑,为工程师提供更强的表达能力从而提升效率。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:小幸运Q

查看原文:golang 泛型

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3840 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传