kotlin的高阶类型通俗理解

最近在看《Kotlin核心编程》这本书,关于高阶类型这一章节晦涩难懂,当然可能与自己的知识水平有关,在参阅其他资料后才大概明白作者的意思,遂作此文,把书本的案例重新编排下。

1、问题

假设我们给集合类型定义了Iterable2<T>的接口,目的为了遍历集合:

interface Iterable2<T> {
    fun iterator(): Iterable2<T>
}

然后让不同的集合实现这个接口,比如列表这样定义:

interface List2<T>: Iterable2<T> {
    override fun iterator(): List2<T>
}

Set中这样定义:

interface Set2<T>: Iterable2<T> {
    override fun iterator(): Set2<T>
}

同样一个接口,就因为返回的集合类型不同,就要在每种集合中都这样定义,100种集合定义100次,对程序员来说是不可接受的!

那有同学说了,可否在Iterable2中加一个类型R,来表示返回的类型,如下:

interface Iterable2<T, R> {
    fun iterator(): R
}

然后我们迅速发现,下面问号不知道该填啥。

interface List2<T>: Iterable2<T, ?> {

}

因为kotlin中没法把List、Set这些类型本身作为泛型的类型参数。

2、设想

我们换个思路,如果有个函数,可以生成List、Set这些集合类型,然后把生成的类型作为上面的R,是不是问题就解决了?

我们姑且把这个函数称为F(X),其中X是集合中的参数类型,可以简单地理解为函数中的自变量,而F(X)就表示某一集合的类型,如F_LIST(T)就是List<T>这个类型本身,F_SET(T)就是Sett<T>这个类型本身。

关于这个“类型本身”,大家可以细品下。

然后,我们改写下Iterable2<T>如下:

interface Iterable2<T, F<X>> {
    fun iterator(): F<T> // 令X = T
}

那么List、Set不用再写重写iterator()方法,可以这样写:

/**
* List#iterator定义
*/
interface List2<T>: Iterable2<F_LIST(T)>
/**
* Set#iterator定义
*/
interface Set2<T>: Iterable2<F_SET(T)>

3、方案

然而……,kotlin中不存在这样的F(X)。

既然没有,我们就创造一个类型,其中F和X都作为变数。

interface Kind<F, X>

就用这个类型来表示F传入X后生成的新类型。

我们再来改写下kotlin版本的Iterable2:

interface Iterable2<F, T> {
    fun Kind<F, T>.iterator(): Kind<F, T>
}

其中T,表示集合的元素类型,iterator()返回的Kind<F, T>表示F传入T后生成的新类型。

细心的朋友应该注意到了,iterator()是Kind<F, T>的扩展方法。

如果所有的集合都继承Kind<F, T>,也就是:

interface List2<T>: Kind<List2.ToListType, T> {
    /**
     * 就是上面提到的F,它就是一个标识,不要去钻牛角尖地考虑怎么实现
     */
    object ToListType
}

那么根据扩展方法的规则,所有集合都有iterator()方法。

那么这样绕来绕去到底有什么用呢?

这时候你会发现,完全不用像最开始那样分别在List、Set中写iterator()了。

用的时候直接用!!!

val listImpl = object : Iterable2<List2.ToListType, String> {
    override fun Kind<List2.ToListType, String>.iterator(): Kind<List2.ToListType, String> {
        TODO("Not yet implemented")
    }
}

根据我们上面定义的Kind<List2.ToListType,String>含义,这个就表示List<String>,尽管看起来仍然很抽象。

其他的集合类型可以同样这样搞大家可以亲自动手试下噢。

剩下的内容大家可以去看《Kotlin核心编程》,这里就不再赘述了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Meta章磊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值