前言
不像Java、Python等编程语言直接或间接的提供了对set的支持。在Go语言中,内置数据类型并没有提供对集合(set)的支持,但是有相当多的场景下都会用到这种数据类型。这时候,就需要我们自己实现这种类型。
实现
所谓集合,不过是由相同或不同数据类型不同元素所组成的。
对于如何实现set,我们可以考虑根据Go语言已有的数据类型,简单的实现set以满足我们的需要。Go语言内置数据类型中有map数据类型,map的底层是依靠的hash实现的,效率非常高,且map数据类型的key是不会重复的,正好这个特性也能满足set元素不重复的特性。由于map数据类型的形式是map[key_type]value_type,即:map是由key-value组成的,而set只包含元素,没有key-value中的value。但是,我们可以考虑使用Go中空结构体struct{}代替value。
我们先声明一个map变量:
1 | var mySet = make(map[int]struct{}, 2) |
上面虽然使用了空结构体struct{}作为set的”value“,但是使用时要写很多的struct{}{},这实在不够简约。现在让我们使用none作为空结构体struct{}的别名。
1 | type none struct{} |
经过以上步骤,基本实现了set的雏形,我们还要做一些收尾工作:定义一个set类型。
1 | type set map[int]none |
现在我们就可以使用set了,首先来实现一些set的函数。
1 | var mySet = make(set, N) |
上面只是简单实现了一些关于set操作的函数,其实我们可以根据需要实现更多对set的操作。
总结
借助Go中的map,我们算以曲线救国的方式实现了set这个缺失的基础数据类型。虽然Go相比与其他语言足够的简约,设计上的简约可能意味着使用实现上的繁琐,就像set的缺失,其实是让人感觉相当遗憾的事,使得我们想要使用它,就得以自己的方式实现,并需要实现这个类型相关的函数或方法。