Kotlin 将 `fun` 实现为 `val`(类似于 Scala 将 `def` 实现为 `val`)

Mik*_*der 1 kotlin

在 Scala 中,您可以trait使用 undefined定义一个def要在实现类中实现的对象。此外, adef可以实现为 adef或 a val

trait Foo { def bar: Int }

class Baz(val bar: Int) extends Foo // ok
Run Code Online (Sandbox Code Playgroud)

对于上下文

  • val 在 Scala 和 Kotlin 中具有相同的含义
  • fun并且def在 Scala 和 Kotlin 中或多或少相同
  • trait并且interface在 Scala 和 Kotlin 中或多或少相同。

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

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

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

interface Foo {
    fun bar(): Int
}

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

Ten*_*r04 5

它可以通过val属性而不是函数来完成。当您使用 just=和 no定义属性时get(),初始化代码将被调用一次并分配给后备变量,因此当访问该属性时,它只是读取存储在后备变量中的值,而无需再次计算:

interface Foo {
    val bar: Int
}

class Baz : Foo {
    override val bar: Int = TODO("Some heavy init function.")
}
Run Code Online (Sandbox Code Playgroud)

并且该接口使您可以灵活地使用自定义 getter 使其按需计算(每次访问可能不同):

class Baz : Foo {
    override val bar: Int get() = Random.nextInt(10)
}
Run Code Online (Sandbox Code Playgroud)

或者使用属性委托延迟计算(第一次访问它而不是在类实例化时):

class Baz : Foo {
    override val bar: Int by lazy { TODO("Some heavy init function.") }
}
Run Code Online (Sandbox Code Playgroud)

或者您可以将其升级为 avar并允许外部类覆盖属性中设置的内容:

class Baz : Foo {
    override var bar: Int = 5
}
Run Code Online (Sandbox Code Playgroud)

或者仅在类内部:

class Baz : Foo {
    override var bar: Int = 5
        private set
}
Run Code Online (Sandbox Code Playgroud)

使用自定义 getter,您可以做一些涉及支持属性的更复杂的事情,类似于带有fun. 或者,如果有重复使用的模式,您可以设计自己的属性委托。