https://kotlinlang.org logo
Title
l

leosan

05/02/2018, 11:55 AM
#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

benleggiero

05/03/2018, 2:53 AM
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 }
   }
}
:kotlin-flag: 1
e

elizarov

05/03/2018, 9:42 AM
It would be even more :kotlin: 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
.
:kotlin: 1
👍 1
b

benleggiero

05/07/2018, 2:10 AM
How is a top-level function named the same as the class name any more Kotlin than an invoke operator function?
e

elizarov

05/08/2018, 2:53 AM
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

benleggiero

05/08/2018, 3:31 AM
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

elizarov

05/08/2018, 12:28 PM
“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

benleggiero

05/08/2018, 12:30 PM
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

elizarov

05/08/2018, 12:33 PM
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

benleggiero

05/08/2018, 12:36 PM
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

elizarov

05/08/2018, 12:39 PM
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

benleggiero

05/08/2018, 3:22 PM
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)