Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule 6.1.4: several init blocks are redundant and generally should not be used in your class #440

Closed
petertrr opened this issue Oct 23, 2020 · 0 comments · Fixed by #459
Closed
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@petertrr
Copy link
Member

petertrr commented Oct 23, 2020

The primary constructor cannot contain any code. That's why Kotlin has introduced init blocks.
These blocks are used to store the code that should be run during the initialization of the class.
Kotlin allows to write multiple initialization blocks that are executed in the same order as they appear in the class body.
Even when you have the (rule 3.2)[#s3.2] this makes code less readable as the programmer needs to keep in mind all init blocks and trace the execution of the code.
So in your code you should try to use single init block to reduce the complexity. In case you need to do some logging or make some calculations before the assignment
of some class property - you can use powerful functional programming. This will reduce the possibility of the error, when occasioanlly someone will change the order of your init blocks.
And it will make the logic of the code more coupled. It is always enough to use one init block to implement your idea in Kotlin.

Bad example A:

class YourClass(var name: String) {    
    init {
        println("First initializer block that prints ${name}")
    }
    
    val property = "Property: ${name.length}".also(::println)
    
    init {
        println("Second initializer block that prints ${name.length}")
    }
}

Good example A:

class YourClass(var name: String) {
    init {
        println("First initializer block that prints ${name}")
    }

    val property = "Property: ${name.length}".also { prop ->
        println(prop)
        println("Second initializer block that prints ${name.length}")
    }
}

Also - init block was not added to Kotlin to help you simply initialize your properties it is needed for more conplex tasks.
So if init block contains only assignments of variables - move it directly to properties so they will be correctly initialized near the declaration.
In some case this rule can be in clash with 6.1.1, but that should not stop you.
Bad example:

class A(baseUrl: String) {
    private val customUrl: String
    init {
        customUrl = "$baseUrl/myUrl"
    }
}

Good example:

class A(baseUrl: String) {
    private val customUrl = "$baseUrl/myUrl"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
1 participant