Just curious: In Kotlin, I would love to get some val that can be initialized by lazy, but with a parameter. That's because I need something that's created very late in order to initialize it.
Specifically, I wish I had:
private lateinit val controlObj:SomeView
or:
private val controlObj:SomeView by lazy { view:View->view.findViewById(...)}
and then:
override fun onCreateView(....) {
val view = inflate(....)
controlObj = view.findViewById(...)
or in the 2nd case controlObj.initWith(view)
or something like that:
return view
I cannot use by lazy
because by lazy
won't accept external parameters to be used when initialising. In this example - the containing view
.
Of course I have lateinit var
but it would be nice if I could make sure it becomes read only after setting and I could do it in one line.
Is there a pretty clean way to create a read only variable that initializes only once but only when some other variables are born? Any init once
keyword? That after init the compiler knows it's immutable?
I am aware of the potential concurrency issues here but if I dare to access it before init, I surely deserve to be thrown.
In this solution you implement a custom delegate and it becomes a separate property on your class. The delegate has a
var
inside, but thecontrolObj
property has the guarantees you want.BTW if you need thread safety, the solution is just slightly different:
For
Activity
it is OK to do follow:For
Fragment
it is not makes sense to createfinal
variable with anyView
type, because you will lost connection with that view afteronDestroyView
.P.S. Use Kotlin synthetic properties to access views in
Activity
andFragment
.You can implement own delegate like this:
After that you can use it as following:
In case when you try to access value before it initialized you will get exception as well as when you try to reassign new value.
also,you can write DSL to make it readable.
and then call it like this:
I believe there is no such thing "init once". Variables are either final or not. lateinit variables are not final. Because, well, you reassign it some other value after initialization phase.
If someone finds the solution, I'm starring this question
You can use
lazy
. For example withTextView
where
view
isgetView()
. And afteronCreateView()
you can usetext
as read only variableYou can implement own delegate like this:
After that you can use it as following:
In case when you try to access value before it initialized you will get exception as well as when you try to reassign new value.