kotlin - Kotlin 将 `fun` 实现为 `val`(类似于 Scala 将 `def` 实现为 `val`)
问题描述
在 Scala 中,您可以trait
使用未定义定义 adef
在实现类中实现。此外,adef
可以实现为 adef
或 a val
。
trait Foo { def bar: Int }
class Baz(val bar: Int) extends Foo // ok
对于上下文
val
在 Scala 和 Kotlin 中具有相同的含义fun
并且def
在 Scala 和 Kotlin 中或多或少相同trait
并且interface
在 Scala 和 Kotlin 中或多或少相同。
这里的优点是 trait 的某些实现可以返回一个在类初始化时设置的 bar 的静态值,而某些实现可以在每次访问 bar 时生成该值。
Kotlin 中是否内置了类似的功能?
我已经厌倦了实施 a fun
as aval
并且那不起作用。我目前有下面的代码,但感觉这里的样板比必要的要多。
interface Foo {
fun bar(): Int
}
class Baz : Foo {
private val _bar: Int = TODO("Some heavy init function.")
override fun bar(): Int = _bar
}
解决方案
它可以用val
属性而不是函数来完成。当您使用 just=
和 no定义属性时get()
,初始化代码被调用一次并分配给支持变量,因此当访问该属性时,它只是读取存储在支持变量中的值而无需再次计算:
interface Foo {
val bar: Int
}
class Baz : Foo {
override val bar: Int = TODO("Some heavy init function.")
}
该接口使您可以灵活地使用自定义 getter 使其按需计算(每次访问可能不同):
class Baz : Foo {
override val bar: Int get() = Random.nextInt(10)
}
或者使用属性委托懒惰地计算(第一次访问它而不是在类实例化时):
class Baz : Foo {
override val bar: Int by lazy { TODO("Some heavy init function.") }
}
或者您可以将其升级为 avar
并允许外部类覆盖属性中设置的内容:
class Baz : Foo {
override var bar: Int = 5
}
或仅在班级内部:
class Baz : Foo {
override var bar: Int = 5
private set
}
使用自定义 getter,您可以做一些涉及支持属性的更复杂的事情,类似于使用fun
. 或者,如果您重复使用某种模式,您可以设计自己的属性委托。
推荐阅读
- asp.net-core - 如何在单例服务中使用数据库上下文?
- ios - 我如何无法在 JSON Array Swift 4 中获取 de 属性
- c# - 匿名操作中的封闭局部变量与预期不符
- python - 插入值作为参数 - Python
- python - Keras Conv1D 或 Convolution1D
- c# - C# 使用 jdbc url 连接到 oracle db
- python - 带有venv的django 2.1环境
- php - PHP 和 AJAX url 获取数据
- apache-kafka - Kafka Streams KTable Store 在这种情况下对于压缩输入主题没有用处,替代方案?
- google-apps-script - 将二维数组传递给创建另一个维度的函数