Expect member declaration error on declared variables in kotlin - kotlin

I'm a beginner in kotlin and I'm getting errors on my variables when I tried using them. please I need help. Here is my code
package com.example.myapplication
import java.util.*
class savedData(hour:Int, Minutes:Int) {
var calendar= Calendar.getInstance()
calendar.set(Calendar.HOUR_OF_DAY,hour )
calendar.set(Calendar.MINUTE,Minutes )
calendar.set(Calendar.SECOND,0 )
}
I get errors when i use the calendar variable in my code above

Your various calendar.set calls need to be inside an init block:
class savedData(hour: Int, minutes: Int) {
var calendar = Calendar.getInstance()
init {
calendar.set(Calendar.HOUR_OF_DAY, hour)
calendar.set(Calendar.MINUTE, minutes)
calendar.set(Calendar.SECOND, 0)
}
}
Class-level statements can only be property declarations, not code to initialize them.
Another approach would be to use a scoping function like apply:
class savedData(hour: Int, minutes: Int) {
var calendar = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, hour)
set(Calendar.MINUTE, minutes)
set(Calendar.SECOND, 0)
}
}

The other 2 answers are basically correct. However, you might also be interested in initializing the property the lazy way, so that it won't be initialized as long as nothing needs it:
class savedData(hour:Int, Minutes:Int) {
var calendar: Calendar by lazy {
Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, hour)
set(Calendar.MINUTE, Minutes)
set(Calendar.SECOND, 0)
}
}
}
This is specially useful for creating an instance of a class with resource-intensive init process.

This will work:
class savedData(hour:Int, Minutes:Int) {
var calendar= Calendar.getInstance().apply{
this.set(Calendar.HOUR_OF_DAY,hour )
this.set(Calendar.MINUTE,Minutes )
this.set(Calendar.SECOND,0)
}
}
Within a class body, its properties and methods are declared. The executable code must be inside these methods (or in init {} block, or in some setters/getters, or in scope functions like above), not in the body of the class.

Related

Is there a way to mock the invocation of a secondary constructor of a Kotlin data class using mockk

From the documentation of mockk.io regarding the mocking capabilities of constructors I can see the following:
class MockCls(private val a: Int = 0) {
constructor(x: String) : this(x.toInt())
fun add(b: Int) = a + b
}
mockkConstructor(MockCls::class)
every { constructedWith<MockCls>().add(1) } returns 2
As far as I understood it is possible to mock the construction of an object and get a result for an executed method.
What I would like to have is e.g. the following
data class MyDataClass(val first: String) {
constructor(anotherDataClass: AnotherDataClass) : this(
first = anotherDataClass.second
)
}
data class AnotherDataClass(val second: String)
mockkConstructor(MyDataClass::class)
every { constructedWith<MyDataClass>() } returns mockk<MyDataClass>
or
every { anyConstructed<MockCls>() } returns mockk<MyDataClass>
In the end, I want to bypass the construction and directly return a constructed mock and not first execute a method and return the result.
Avoiding constructor execution while mocking not currently (<=1.12.0) possible by design (https://github.com/mockk/mockk/issues/515)
If you really want to capture instance while doing constructor mocking, you can get away with this:
val myMockedInstance: MyClass = MockKGateway.implementation().constructorMockFactory.mockPlaceholder(
MyClass::class,
args = arrayOf<Matcher<*>>(
EqMatcher(dummyParamOfMine)
) as Array<Matcher<*>>
)

Koin - How to generify Singleton creation?

I have a class InteractorCache<T> that I would like to inject in different places using Koin.
I would like to create a singleton instance of that class based on the type T. So if I have 10 types T, I would like 10 different singletons.
So far I managed to do the above with the following code (this is an example with only 2 types, A and B):
val interactorAModule = module {
factory {
InteractorA(get())
}
}
val aCache = module {
single(named("A")){
InteractorCache<List<A>>()
}
}
val interactorBModule = module {
factory {
InteractorB(get())
}
}
val bCache = module {
single(named("B")){
InteractorCache<List<B>>()
}
}
This works but there is a lot of repetition as I have to create a new cache module (aCache, bCache) every time I create a new type. I would like to be able to do something like this instead:
val cacheModule = module{
single<T>{
InteractorCache<T>()
}
}
so there is only 1 declaration that works for any type T.
Is there a way to do this in Koin?
Although this is late but the idea of making generic or T a singleton is bad idea, when you declare a class singleton it will run a single instance, so runtime error would be InteractorCache() is incompatible or mismatched to InteractorCache() as the first class you would assign the T for example the class A InteractorCache() it would be fixed instance of A and cannot anymore assign to class B.

Subclass var initialization step and OOP structure design

The abstract super class Parent has abstract method extract(Int), getting the value a from primary constructor, and submit it to that method extract(a).
abstract class Parent ( val a : Int ) {
abstract fun extract ( i : Int )
init {
// call overriden extract(Int)
extract ( a )
}
}
The sub class Child defines the method extract(Int), sending the value b to the Parent's constructor, then the super class Parent calling extract(Int) to set that value to Child's variable x.
class Child ( b : Int ) : Parent ( b ) {
// initialize x variable to -1
var x : Int = -1
override fun extract ( i : Int ) {
// set x to given int
x = i
}
}
Testing:
println ( Child ( 10 ).x )
And got:
-1
Now, try adding init{} of the sub class Child
init {
x = -2
}
Testing again:
println ( Child ( 10 ).x )
And got:
-2
Seemingly, the init{} of sub class Child is done after the super class Parent's construction.
Should the extract(Int) be overridden ann called by all sub classes, rather than by the super class?
I am not sure what you mean by "super class Child", but it seems you may be confused of the order of derived classes. Here is a really good example that shows the order. It has a code snippet that you can run on the site.
Generally speaking this kind of initializer interaction is frowned upon, since the exact order of operations, while well defined, is often counter-intuitive.
Specifically, what I believe is happening here, might be more clear using the more verbose explicit-constructor syntax in kotlin. You're code is an abbreviated version of this (note, this is legal kotlin):
abstract class Parent {
val a: Int
constructor(a: Int){
this.a = a
extract(a)
}
abstract fun extract ( i : Int )
}
class Child: Parent {
var x : Int
constructor(b: Int): Parent(b) {
//super.constructor(b) fires here
// initialize x variable to -1
x = -1
}
override fun extract (i : Int) {
// set x to given int
x = i
}
}
thus, as I hope is now a little more clear, a pseudo-call-trace is like this:
enter Child.constructor(10)
enter Parent.constructor(10)
assign 10 to this#Parent.a
enter this.extract(10) => V-Table resolves Child.extract()
assign 10 to this#Child.x
extract returns
Parent.constructor returns
assign -1 to this#Child.x this is probably your point of confusion
Child.constructor returns
What you can do
Generally speaking, when you encounter confusing initialization flows, the answer on the JVM is to formalize the complex initialization in another method, rather than in more init or constructors.
In kotlin the simplest way to do this --and a strategy used by many many libraries-- is to create a static factory method.
abstract class Parent(val a: Int) {
//...
}
class Child private constructor(var x: Int): Parent(x) {
companion object {
fun makeChild(unextracted: Int) {
val extracted = extract(unextracted)
return Child(extracted)
}
// a first good step is to make `extract` referentially transparent
// aka pure
// IE all of its function is provided in its return type
fun extract (i : Int): Int {
return i //do appropriate transforms.
//note, if you need multiple return values here, consider Pairs or Triples.
}
}
}
Note, kotlin provides some syntax sugar for this, you can override the invoke operator:
class Child { companion object { operator fun invoke(x: Int) { ... } } }
which means that instead of makeChild (eg Child.makeChild(10)) to call your factory function you to use ~constructor syntax (Child(10)).
Even more generally, if you find yourself running into this problem under an IOC container which, for whatever reason, must use initializer flow, I would encourage you to refactor your IOC consumers to use old-fashioned java factories. I'll need more details to elaborate here.

How to write a package-level static initializer in Kotlin?

A previous question shows how to put a static initializer inside a class using its companion object. I'm trying to find a way to add a static initializer at the package level, but it seems packages have no companion object.
// compiler error: Modifier 'companion' is not applicable inside 'file'
companion object { init { println("Loaded!") } }
fun main(args: Array<String>) { println("run!") }
I've tried other variations that might've made sense (init on its own, static), and I know as a workaround I can use a throwaway val as in
val static_init = {
println("ugly workaround")
}()
but is there a clean, official way to achieve the same result?
Edit: As #mfulton26's answer mentions, there is no such thing as a package-level function really in the JVM. Behind the scenes, the kotlin compiler is wrapping any free functions, including main in a class. I'm trying to add a static initializer to that class -- the class being generated by kotlin for the free functions declared in the file.
Currently there is no way to add code to the static constructor generated for Kotlin file classes, only top-level property initializers are getting there. This sounds like a feature request, so now there is an issue to track this: KT-13486 Package-level 'init' blocks
Another workaround is to place initialization in top-level private/internal object and reference that object in those functions that depend on the effect of that initialization. Objects are initialized lazily, when they are referenced first time.
fun dependsOnState(arg: Int) = State.run {
arg + value
}
private object State {
val value: Int
init {
value = 42
println("State was initialized")
}
}
As you mentioned, you need a property with something that would run on initialisation:
val x = run {
println("The package class has loaded")
}
I got around it by using a Backing Property on the top-level, under the Kotlin file. 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")
}

How do I initialize a final field in Kotlin?

Let's say I declared a final field with private final String s (Java) or val s (Kotlin). During initialization I want to initialize the field with the result of a call to a remote service. In Java I would be able to initialize it in the constructor (e.g. s = RemoteService.result()), but in Kotlin I can't figure out how to do that because as far as I can tell the field has to be initialized in the same line it's declared. What's the solution here?
You can set val value in init block:
class MyClass {
val s: String
init {
s = "value"
}
}
You can also initialize the value with by lazy the value will be initialized the first time it is referred. An example
val s by lazy { RemoteService.result() }
kotlin will guess the type of s from the return type of the expression.
You can use run:
class MyClazz {
val prop = run {
// do stuff
// do stuff again
123 // return expression
}
}
From the docs (emphasis is mine):
Besides calling run on a receiver object, you can use it as a non-extension function. Non-extension run lets you execute a block of several statements where an expression is required.
It has been possible to do it simply like this since the very first official stable release of Kotlin:
class MyClass {
val s = RemoteService.result()
}