``` #SWIFT enum NumberCategory { case Small ...
# getting-started
l
Copy code
#SWIFT
enum NumberCategory {
   case Small
   case Medium
   case Big
   case Huge
   init(number n: Int) {
    if n < 10000 { self = .Small }
    else if n < 1000000 { self = .Medium }
    else if n < 100000000 { self = .Big }
    else { self = .Huge }
   }
}
How I can achieve something like this in kotlin? Just to illustrate my problem I have a bunch of business logic conditionals that I want to convert to a type and send it to my view, I’m not even sure if this is the best solution or I stick with boolean methods
b
Copy code
enum class NumberCategory {
   Small,
   Medium,
   Big,
   Huge;

   companion object {
      operator fun invoke(n: Int) =
         if (n < 10000) { Small }
         else if (n < 1000000) { Medium }
         else if (n < 100000000) { Big }
         else { Huge }
   }
}
K 1
e
It would be even more K if you rewrite it using
when
. And even more compliant to official Kotlin style if you use top-level constructor-like function named
NumberCategory
instead of
companion object
.
K 1
👍 1
b
How is a top-level function named the same as the class name any more Kotlin than an invoke operator function?
e
That is approach that is used in Kotlin standard library and is generally a preferred one — it is easier to understand and does not look as magic.
b
I don’t think a language feature as simple as an
operator fun
is magic… Perhaps if it’s seen as such by the writers of stdlib, then it should be rethought. Perhaps we should allow factory-style constructors
e
“Magic” here means “harder to understand for novices”.
operator fun invoke
is a useful feature for certain DSL, but using it just to define a “factory function” requires too much syntax and boilerplate. A top-level function with the corresponding name solves the same problem simpler, more directly, with less code.
b
Wait, so why would stdlib use it? If there use site is identical then you mean the novices are the ones writing the library, not the ones using it?? Also something I dislike about that approach is the IDE syntax-highlighting it as a function when it's used as a constructor
e
Stdlib is using constructor functions, take a look here, for example: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list.html
It is an open design question on better integration of those constructor functions into the language itself. Currently, it is just a convention.
b
I think it's silly for the same team (presumably) that went through the trouble of inventing/approving the invoke pattern, which does this thing they are mimicking, would not use it because they think it's too complicated. Says a lot.
e
I’m not sure I understand your idea.
operator fun invoke
was primarily designed for function-like objects and classes (all function types have it, for example). Using it on
companion object
is clever hack, indeed, but understandable software should not be built using clever hacks.
b
Sure, and the JVM was primarily designed for webpage applets, but we found much better uses for it. I don't think it's a "clever hack" using it this way... This seems very intended. If it wasn't intended, I'd expect its syntax to be
MyClass.Companion(arguments)
, but it's
MyClass(arguments)