【问题标题】:How to implement a Kotlin interface that refers to the conforming type?如何实现引用符合类型的 Kotlin 接口?
【发布时间】:2019-03-03 16:17:02
【问题描述】:

出于愚蠢的思想实验的兴趣,其主要目的是探索语言的一部分是如何工作的,我决定探索一种让 Python 程序员更适应 Kotlin 的方法。简单地说,我可以通过添加:

class Foo {
    private val self:Foo get() = this
    ...
}

(旁白问题:是否有更通用的方式将Foo 称为那里的返回类型,这样如果我将Foo 更改为Barself 的变量类型仍将引用“这个方法的实现类”?)

虽然必须在每个类中都添加这条线,这样我们才能感到自私地 Python 化,但这很乏味。所以我转向了一个接口。我最初想要的是类似于 Swift 的 Self 协议类型。但我在 Kotlin 中找不到类似的东西。在阅读了https://kotlinlang.org/docs/reference/generics.html(这似乎与 Java 和 Kotlin 一样多)之后,我得出结论,也许“声明站点差异”对我来说很重要:

interface Selfish<out T> {
    val self:T get() = this as T
}

class Foo:Selfish<Foo> {
}

这样更好。我必须在声明中两次列出类名是不可取的,但我认为没有办法解决这个问题。有吗?

此外,这适用于最终类,但如果我想在根级别有一个符合 Selfish 的类层次结构,事情就会崩溃:

class Foo:Selfish<Foo> { ... }
class Bar:Foo { ... }

Bar 中使用self 的方法属于错误类型。添加, Selfish&lt;Bar&gt; 会产生冲突。

是否有我尚未发现的工具可以使类型引用继承的类型?

有没有其他方法(除了接口)来做这样的事情?

我是否在使用“声明站点差异”时做出了错误的选择?

【问题讨论】:

  • 我相信您需要循环通用模式。
  • 我可以假装我理解@OliverCharlesworth 的意思,但我只是在假装。

标签: generics kotlin generic-variance


【解决方案1】:

我觉得你应该看看extensions

所以你可以写

fun <T>Foo.getSelf(): T {
    return this as T
}

如果你有

open class Foo

class Bar: Foo()

所以

Bar().getSelf<Bar>()

将返回 Bar 类的对象

或者更简单,你可以写

fun <T:Foo>T.getSelf(): T {
    return this as T
}

这样你就可以打电话了

Bar().getSelf()

获取从 Foo 扩展的任何类的实例

【讨论】:

    【解决方案2】:

    根据@DEADMC 的建议,我选择了全局扩展名val,而不是fun。它没有回答在不使用泛型模式的情况下如何在实现中普遍引用符合类型的问题,但它确实以更简单和可扩展的方式解决了更大的问题:

    val <Anything>Anything.self:Anything inline get() = this
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-04
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      相关资源
      最近更新 更多