前言
不像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
的缺失,其实是让人感觉相当遗憾的事,使得我们想要使用它,就得以自己的方式实现,并需要实现这个类型相关的函数或方法。