如何实现引用符合类型的 Kotlin 接口?
How to implement a Kotlin interface that refers to the conforming type?
出于主要目的是探索语言的一部分如何工作的愚蠢思想实验的兴趣,我决定探索一种让 Python 程序员在 Kotlin 中更舒适的方法。简单地说,我可以通过添加来做到这一点:
class Foo {
private val self:Foo get() = this
...
}
(旁白问题:是否有更通用的方法将 Foo
称为 return 类型,这样如果我将 Foo
更改为 Bar
, self
的变量类型仍会引用 "implementing class of this method"?)
必须在每个 class 中加上那一行,这样我们才能感觉到自私的 pythonic 是乏味的。所以我转向了一个界面。我最初想要的是类似于 Swift 的 Self
协议类型。但我在 Kotlin 中找不到类似的东西。在阅读 https://kotlinlang.org/docs/reference/generics.html(这似乎和 Kotlin 一样多 Java)之后,我得出结论,也许 "Declaration Site Variance" 对我来说是正确的:
interface Selfish<out T> {
val self:T get() = this as T
}
class Foo:Selfish<Foo> {
}
这样更好。我不希望在声明中列出两次 class 名称,但我认为没有办法解决这个问题。有吗?
此外,这适用于最终的 classes,但如果我想要一个 class 层次结构在根级别符合自私,事情就会崩溃:
class Foo:Selfish<Foo> { ... }
class Bar:Foo { ... }
Bar 中使用 self
的方法类型错误。添加 , Selfish<Bar>
会产生冲突。
有没有我还没有发现的工具可以使类型引用继承类型?
是否有其他方法(除了接口)可以做这样的事情?
我使用 "Declaration Site Variance" 是不是选错了?
我觉得你应该看看extensions。
所以你可以这样写
fun <T>Foo.getSelf(): T {
return this as T
}
那么如果你有
open class Foo
class Bar: Foo()
所以
Bar().getSelf<Bar>()
将 return 对象 Bar
class
或者更简单,你可以写
fun <T:Foo>T.getSelf(): T {
return this as T
}
所以你可以只调用
Bar().getSelf()
获取从 Foo
扩展的任何 class 的实例
根据@DEADMC 的建议,我使用了全局扩展 val
而不是 fun
。它没有回答您如何在不使用通用模式的情况下在实现中普遍引用符合类型的问题,但它确实以更简单和可扩展的方式解决了更大的问题:
val <Anything>Anything.self:Anything inline get() = this
出于主要目的是探索语言的一部分如何工作的愚蠢思想实验的兴趣,我决定探索一种让 Python 程序员在 Kotlin 中更舒适的方法。简单地说,我可以通过添加来做到这一点:
class Foo {
private val self:Foo get() = this
...
}
(旁白问题:是否有更通用的方法将 Foo
称为 return 类型,这样如果我将 Foo
更改为 Bar
, self
的变量类型仍会引用 "implementing class of this method"?)
必须在每个 class 中加上那一行,这样我们才能感觉到自私的 pythonic 是乏味的。所以我转向了一个界面。我最初想要的是类似于 Swift 的 Self
协议类型。但我在 Kotlin 中找不到类似的东西。在阅读 https://kotlinlang.org/docs/reference/generics.html(这似乎和 Kotlin 一样多 Java)之后,我得出结论,也许 "Declaration Site Variance" 对我来说是正确的:
interface Selfish<out T> {
val self:T get() = this as T
}
class Foo:Selfish<Foo> {
}
这样更好。我不希望在声明中列出两次 class 名称,但我认为没有办法解决这个问题。有吗?
此外,这适用于最终的 classes,但如果我想要一个 class 层次结构在根级别符合自私,事情就会崩溃:
class Foo:Selfish<Foo> { ... }
class Bar:Foo { ... }
Bar 中使用 self
的方法类型错误。添加 , Selfish<Bar>
会产生冲突。
有没有我还没有发现的工具可以使类型引用继承类型?
是否有其他方法(除了接口)可以做这样的事情?
我使用 "Declaration Site Variance" 是不是选错了?
我觉得你应该看看extensions。
所以你可以这样写
fun <T>Foo.getSelf(): T {
return this as T
}
那么如果你有
open class Foo
class Bar: Foo()
所以
Bar().getSelf<Bar>()
将 return 对象 Bar
class
或者更简单,你可以写
fun <T:Foo>T.getSelf(): T {
return this as T
}
所以你可以只调用
Bar().getSelf()
获取从 Foo
扩展的任何 class 的实例根据@DEADMC 的建议,我使用了全局扩展 val
而不是 fun
。它没有回答您如何在不使用通用模式的情况下在实现中普遍引用符合类型的问题,但它确实以更简单和可扩展的方式解决了更大的问题:
val <Anything>Anything.self:Anything inline get() = this