I am trying to make a static array in Kotlin. For doing this, I created an Object class, and inside that declared a mutableListOf<PersonModel>()
.
When I try to add new Object PersonModel
to array, I get red underline suggesting error in last line, which says Expecting member declaration
.
Code
object Data {
val array = mutableListOf<PersonModel> (PersonModel("roshan",65,50,"White",21,"male"))
array.add(PersonModel("roshan",65,50,"White",21,"male"))
}
CodePudding user response:
Here's my suggestion code:
// place the object class constructor //
class PersonModel (var name: String, var a: Int, var b: Int, var color: String, var c: Int, var sex: String)
// create your first object //
val array = mutableListOf<PersonModel>(PersonModel("roshan",65,50,"White",21,"male"))
// add the second object //
array.add(PersonModel("minotiana",30,10,"White",21,"Male"))
CodePudding user response:
You can't use arbitrary executable code inside object/class declaration. This code block is only for defining of class members. If you want to execute some code when the class is instantiated, you can use initialization block:
object Data {
val array = mutableListOf<PersonModel> (PersonModel("roshan",65,50,"White",21,"male"))
init {
array.add(PersonModel("roshan",65,50,"White",21,"male"))
}
}
If you prefer to keep initialization code for a member in a single place, a common pattern is to use scope function, for example run()
or apply()
:
val array = mutableListOf<PersonModel>().apply {
add(PersonModel("roshan",65,50,"White",21,"male"))
add(PersonModel("roshan",65,50,"White",21,"male"))
}
In your specific case, you don't have to do this, because you can create a list with both items directly:
val array = mutableListOf<PersonModel> (
PersonModel("roshan",65,50,"White",21,"male"),
PersonModel("roshan",65,50,"White",21,"male"),
)
CodePudding user response:
As written by @Arpit Shukl in the comments, one cannot add arbitrary statements such as array.add(...)
to the body of an object (or class) declaration.
To achieve a statically initialized, globally available variable (or value) in Kotlin, you have multiple options.
Top-level declaration
In Kotlin you can declare var
iables / val
ues and fun
ctions on the top-level without the need for a wrapping object (or class).
package com.example.models
val availablePersonModels = listOf(
PersonModel("roshan", 65, 50, "White", 21, "male")
)
import com.example.models.availablePersonModels
fun foo() {
for (availablePersonModel in availablePersonModels) {
println(availablePersonModel)
}
}
If you want to be able to add / remove items from the list after initialization, simply exchange listOf
with mutableListOf
.
Object declaration
If you want to group several declarations together or make the declaration context more explicit, you may wrap the declaration in an object
.
object ModelProvider {
val availablePersonModels = listOf(
PersonModel("roshan", 65, 50, "White", 21, "male")
)
}
import com.example.models.ModelProvider
fun foo() {
for (availablePersonModel in ModelProvider.availablePersonModels) {
println(availablePersonModel)
}
}
Initializing static values using statements
The listOf
and mutableListOf
function calls support being passed values to add to the created List
, thus you do NOT need to call add(...)
as part of the initialization. However, that must not be the case always.
E.g. there might be classes that need to be instantiated with an empty constructor and filled with values by calling setters afterdwards.
class ExampleClass {
var x: Int? = null
var y: Int? = null
}
Using the object declaration above, you might want to add such calls into the constructor
of the object
, e.g.:
object ModelProvider {
val exampleValue = ExampleClass()
init {
exampleValue.x = 1
exampleValue.y = 1
}
}
Instead of splitting the initialization and population like above, you might also use a single expression for both, e.g. using one of the scope functions such as apply
, e.g.:
val exampleValue = ExampleClass().apply {
x = 1
y = 1
}
Of course this can be used inside an object
as well, removing the need for the init
block.