首页 > 解决方案 > 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

对于上下文

这里的优点是 trait 的某些实现可以返回一个在类初始化时设置的 bar 的静态值,而某些实现可以在每次访问 bar 时生成该值。

Kotlin 中是否内置了类似的功能?

我已经厌倦了实施 a funas aval并且那不起作用。我目前有下面的代码,但感觉这里的样板比必要的要多。

interface Foo {
    fun bar(): Int
}

class Baz : Foo {
    private val _bar: Int = TODO("Some heavy init function.") 
    override fun bar(): Int = _bar
}

标签: kotlin

解决方案


它可以用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. 或者,如果您重复使用某种模式,您可以设计自己的属性委托。


推荐阅读