如何在Kotlin中编写包级静态初始化程序?

时间:2016-08-16 17:04:29

标签: kotlin

A previous question显示了如何使用companion object将静态初始化程序放入类中。我正在尝试找到一种在包级别添加静态初始化程序的方法,但似乎包没有配套对象。

// compiler error: Modifier 'companion' is not applicable inside 'file'
companion object { init { println("Loaded!") } }
fun main(args: Array<String>) { println("run!") }

我尝试了其他可能有意义的变体(initstatic),我知道作为一种解决方法,我可以使用一次性val

val static_init = {
    println("ugly workaround")
}()

但有没有一种干净,官方的方式来达到同样的效果?

编辑:正如@mfulton26's answer所提到的那样,JVM中没有真正的包级函数。在幕后,kotlin编译器是wrapping any free functions, including main in a class。我正在尝试向 类添加静态初始化程序 - 由kotlin为文件中声明的自由函数生成的类。

3 个答案:

答案 0 :(得分:7)

目前无法将代码添加到为Kotlin文件类生成的静态构造函数中,只有顶级属性初始值设定项才能到达。这听起来像是一个功能请求,所以现在有一个问题需要跟踪:KT-13486包级“init”块

另一种解决方法是将初始化放在顶级私有/内部对象中,并在那些依赖于初始化效果的函数中引用该对象。当第一次引用对象时,对象会被懒惰地初始化。

fun dependsOnState(arg: Int) = State.run {
    arg + value
}

private object State {
    val value: Int
    init {
        value = 42
        println("State was initialized")
    }
}

答案 1 :(得分:3)

正如您所提到的,您需要一个可以在初始化时运行的属性:

public class PatientModel : IMapFrom<Patient>, IHaveCustomMappings
{
    public string Id { get; set; }
    public PersonalDataModel PersonalDataModel { get; set; }
}

答案 2 :(得分:0)

我在Kotlin文件下使用顶层的Backing Property来解决这个问题。 Kotlin Docs: Backing Properties

private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
    get() {
        if (_table == null) {
            _table = HashMap() // Type parameters are inferred
           // .... some other initialising code here
        }
        return _table ?: throw AssertionError("Set to null by another thread")
    }