3

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

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

(除了问题:是否有更通用的方式来指代Foo那里的返回类型,以便如果我更改FooBar,变量类型self仍将引用“此方法的实现类”?)

不得不在每个类中都写上这条线,这样我们才能感到自私地 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<Bar>会产生冲突。

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

是否有另一种方法(除了接口)来做这样的事情?

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

4

2 回答 2

2

我认为你应该看看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 扩展的任何类的实例

于 2018-09-27T21:18:10.290 回答
0

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

val <Anything>Anything.self:Anything inline get() = this
于 2018-10-01T23:14:33.030 回答