CLOVIS
04/04/2023, 11:48 AMoperator invoke
to create a constructor-like function. In my opinion, this is an anti-pattern, because it makes code harder to understand and the IDEA integration more confusing for beginners (you have to click on the opening parentheses to go to the source code, not on the function name!). To my knowledge, it's also never used in the standard library or any other official library, which all use top-level functions with the same name as the class to do this (Array
, List
, ...).Alejandro Serrano Mena
04/04/2023, 11:49 AMAlejandro Serrano Mena
04/04/2023, 11:50 AMAlejandro Serrano Mena
04/04/2023, 11:50 AMCLOVIS
04/04/2023, 11:51 AMCLOVIS
04/04/2023, 11:52 AMMarko Novakovic
04/04/2023, 11:59 AMCLOVIS
04/04/2023, 12:01 PMsimon.vergauwen
04/04/2023, 12:01 PMoperator fun invoke
• fun ClassName(...): ClassName
The only real reason for using the former is that it gives you access to private constructor
. Otherwise it requires you to make the constructor internal
. Or you need to define fun ClassName
on the Companion
which is also a bit strange 🤔
I do prefer the latter though, after a lot of back-and-forth but I do miss file private support from Scala to overcome the private constructor
issue.simon.vergauwen
04/04/2023, 12:05 PMdata class
it doesn't even matter since copy
can still break the contract. I was going to say the private constructor
there completely eliminates the ability to constructor incorrect instances...
We'll have to wait on multi-field value class
for that.CLOVIS
04/04/2023, 12:11 PMprivate
on the primary constructor meant private-in-file and not private-in-class, but wellsimon.vergauwen
04/04/2023, 12:20 PMcopy
caveat 😅 and/or suggest a solution. IIRC there was a compiler-plugin for that, and now I guess two with DataClassGenerate.Javier
04/04/2023, 12:25 PMWilerson Oliveira
04/04/2023, 12:44 PMcopy
caveat, one alternative would be to run the checks on init
, but that would lead to duplication and to throwing, which is probably not desirableasdf asdf
04/04/2023, 12:47 PMinvoke
on a companion object is that it has to be manually imported as intellij doesn’t give auto completion for operator functions (unless there’s a setting I don’t know that changes that)simon.vergauwen
04/04/2023, 12:48 PMinvoke
😮Javier
04/04/2023, 12:48 PMCLOVIS
04/04/2023, 12:48 PMasdf asdf
04/04/2023, 2:17 PMasdf asdf
04/04/2023, 2:17 PMstojan
04/04/2023, 2:23 PMMutableStateFlow
is a function.
from what I remember, the kotlin team does NOT recommend the invoke on companion object because the companion object creates an object in bytecode.
for this specific example (the user example of the docs) we can get around the issue (data classes having copy) by using:
@JvmInline value class Age private constructor(val value: Int)
+ factory function (which returns Either
) 🙂
then data class User (val name: String, val age: Age)
simon.vergauwen
04/04/2023, 3:01 PMAge
without companion object
and without removing private
from constructor? 🧌stojan
04/04/2023, 3:03 PMprivate constructor
😄 ....simon.vergauwen
04/04/2023, 3:07 PM@JvmInline value class Age private constructor(val value: Int) {
companion object {
fun Age(...): Either<Error, Age> = ...
}
}
It's used by Duration, some KotlinX libraries (datetime?), .. 🤔
Albeit it's also a bit strange. Should we update towards this? It combines the benefits of all I think.simon.vergauwen
04/04/2023, 3:08 PMAge(..
it'll resolve, and automatically add the import my.pack.Age.Companion.Age
stojan
04/04/2023, 3:08 PMAge
example is, that unless properties depend on each other (like openDate should be before closeDate of a bank account) you can typically push the opaque type up, towards the individual properties.... Then copy doesn't break your invariantsstojan
04/04/2023, 3:09 PMsimon.vergauwen
04/04/2023, 3:11 PMmitch
04/05/2023, 11:23 AM