https://kotlinlang.org logo
#getting-started
Title
# getting-started
j

Jérémy CROS

10/12/2021, 3:31 PM
Hey guys 🙂 Was looking to do something like that but it doesn’t seem to be allowed
Copy code
data class Foo(val a:Int, val b = 0)
val bar = Foo(a = 3, if(param) b = 5 /*else keep the default param */)
Is there an alternative other than
val bar = if(param) Foo(...) else Foo(...)
🚫 3
h

Holden Easley

10/12/2021, 3:32 PM
Its not pretty but something like
Copy code
Foo(a = 3).let { 
  if (param) it.copy(b = 5) else it
}
??
j

Jérémy CROS

10/12/2021, 3:39 PM
hmm, not sure I like it but it’s still an interesting alternative, thanks 🙂 will try with the actual code see how it feels
c

Connor Ford

10/12/2021, 3:41 PM
maybe this is more readable?
Copy code
data class Foo(val a: Int, val b: Int = DEFAULT_B) {
    constructor(a: Int, p: Boolean): this(a, if (p) a else DEFAULT_B)

    companion object {
        private const val DEFAULT_B = 0
    }
}
c

CLOVIS

10/12/2021, 5:23 PM
Out of curiosity, what is the use-case? That seems like it would make the code much harder to understand
👍 1
s

Stephan Schroeder

10/13/2021, 7:24 AM
how about
Copy code
data class Foo(val a:Int, val b = 0)
val bar = if(param) {
  Foo(3, 5)
} else {
  Foo(3)
}
e

ephemient

10/13/2021, 7:33 AM
Copy code
with(Foo::class.primaryConstructor!!) {
    callBy(listOfNotNull("a" to 3, if (param) "b" to 5 else null).associate { (name, value) -> parameters.single { it.name == name } to value })
}
blob thinking upside down
😆 4
🤣 1
IIRC Moshi does the equivalent of
Copy code
Foo::class.java
    .getDeclaredConstructor(Int::class.java, Int::class.java, Int::class.java, kotlin.jvm.internal.DefaultConstructorMarker::class.java)
    .newInstance(3, if (param) 5 else 0 /* this value doesn't matter */, if (param) 0 else 2 /* bitmask */, null)
yeah you can see the implementation in https://github.com/square/moshi/pull/896
a

Alex

10/13/2021, 8:34 AM
@Jérémy CROS, what does param refer to?
j

Jérémy CROS

10/13/2021, 9:19 AM
It’s just a simple boolean with a business meaning. The solution first suggested is actually decently readable when used with the actual code.
Copy code
return ActionInfrastructureUntilLevel(
    buildAction(instructionHumanized.humanInstruction.action),
    buildDirectionalInfrastructure(
        instructionHumanized.humanInstruction.infrastructure
    ),
    infrastructureUntilLevel.level,
    infrastructureUntilLevel.label
).let {
    if (isFirstInstructionAnInfrastructure)
        it.copy(template = R.string.sentence_template_infrastructure_until_level_first)
    else it
}
it’s basically a sentence builder with optional template parameter that are later used for translation. In that case, the simple if else as suggested by @Stephan Schroeder looks worse, IMO Won’t comment on @ephemient trolling me though 😛
👍 1
e

ephemient

10/13/2021, 9:27 AM
heh. sorry about trolling with callBy, I couldn't resist. although I think the synthetic constructor trick is actually useful until KT-18695 has a resolution, it's not worth it unless you're dealing with a situation where you may have a combinatorial explosion of default args
j

Jérémy CROS

10/13/2021, 9:29 AM
haha, yes. And thanks for the link btw, will monitor this one 🙂
2 Views