Byron Katz
05/21/2021, 5:50 PMhho
05/25/2021, 4:56 PMjava.lang.Enum
...
sealed class EnumBinding<E : Enum<E>>(
private val enumType: Class<E>
) : Binding<Any?, E?> {
override fun converter(): Converter<Any?, E?> = object : Converter<Any?, E?> {
override fun from(databaseObject: Any?): E? =
databaseObject?.let { java.lang.Enum.valueOf(enumType, it.toString()) }
…
}
…
}
(it's a custom jOOQ binding, so I can't change Binding
or Converter
)KV
06/16/2021, 1:41 PMviewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
collectABCState()
}
launch {
collectABCInfo()
}
launch {
collectXYZFailedEvents()
}
launch {
collectABCTime()
}
launch {
collectABCSummary()
}
}
Andrew K
06/24/2021, 12:00 AMfind
extension in addition to an Int? Is there anything else I can do to optimize as well?
infix fun <T> T?.ifNull(block: () -> T?) = this ?: block()
inline fun <reified T> EnumCompanion<T>.find(value: Int): T? where T : Enum<T>, T : EnumValue<T> =
enumValues<T>().run {
firstOrNull { (it.value as Int) == value }
.ifNull { firstOrNull { it.name == "Unknown" } }
.ifNull { throw Exception("Enum value does not exist") }
}
interface EnumCompanion<T : Enum<T>>
interface EnumValue<T> {
val value: T
}
enum class MyEnum(override val value: Int) : EnumValue<Int> {
Unknown(0),
First(1),
Second(2),
Third(3);
companion object : EnumCompanion<MyEnum>
}
MyEnum.find(1)
hho
06/28/2021, 4:08 PMcheck(…)
and 2️⃣ require(…)
. Which would be better to signal an invalid configuration (i.e. on startup)? Or should I make up 3️⃣ my own exception class?
I'm really torn between "a bad config is an illegal argument" and "the app is in an illegal state and can't start" 😕oday
07/06/2021, 11:19 AMKV
07/28/2021, 8:40 AM/** Returns the signed in users ID as a `String` or `null` if no ID in shared preferences found (or `0`). */
fun SharedPreferencesManager.userId(): String? {
val userIdLong: Long = this.loadCurrentAdminPsid()
return if (userIdLong == 0L) null else userIdLong.toString()
}
Nick
08/18/2021, 3:18 PMStateFlow
and change it’s value when the camera changes. Additionally, I want to be able to set captureMode manually. But since captureMode is a stateFlow, I can’t set it. Is there a better way?bodiam
09/01/2021, 12:32 PMlateinit var childFolder1 : FolderNode
lateinit var childFolder2 : FolderNode
val rootFolder = buildFolders(am,"System") {
childFolder1 = folder("A") {
+entry(Attribute("x"), Sample("1"))
}
childFolder2 = folder("A") {
+entry(Attribute("x"), Sample("2"))
+entry(Attribute("x"), Sample("2"))
}
+childFolder1
+childFolder2
}
println(childFolder1) // simplified here
As you can see, I need a reference to childFolder1 in my code, but my current solution seems a bit non-idiomatic, so I was wondering if you have any suggestions on how to improve this?
(I’m also not sure if this is the right channel, the new setup confuses me a bit, so if I need to post this somewhere else, please let me know)sbyrne
09/02/2021, 12:52 PMas?
. Is there a better way to chain casts, or something similar in the stdlib that I missed?Jukka Siivonen
09/07/2021, 1:36 PMrocketraman
09/09/2021, 7:46 PMServiceException
to an implementation of some sealed payload interface T
e.g.:
inline fun <reified T> ServiceException.toError(): T {
return when(this) {
is InvalidInputException -> InvalidInputError(...)
is PermissionDeniedException -> PermissionDeniedError(...)
} as T
}
The payload type T
is some interface. I can cast the result of the when
to T as shown, but then forgetting to implement T
in each of these error types will result in a run-time exception.
What would be the best way to create a re-usable function here that is compile-time type-validated, just as if that function were literally inlined?Simon Lin
09/10/2021, 8:43 AMval text = "aas211w"
if (text.any { it.isDigit() } && text.any { it.isLetter() }) {
}
smallufo
09/17/2021, 5:29 PMinterface ICalculate {
fun multiply(a: Int, b: Int): Int
}
It just multiplies a
and b
, and return the result . Suppose it is a heavy computation work . And there are two implementations :
class CalculatorDumb : ICalculate {
override fun multiply(a: Int, b: Int): Int {
var sum = 0
(1..a).forEach {
(1..b).forEach {
sum++
}
}
return sum
}
}
The dumb implementation just add one by one .
class CalculatorSmart : ICalculate {
override fun multiply(a: Int, b: Int): Int {
return a * b
}
}
And this smart implementation just returns a * b
.
OK , here is the point . I hope client can initialize no matter dumb or smart implementation , and can get result if the parameter is identical.
There is a Memoize
pattern , described here : https://jorgecastillo.dev/kotlin-purity-and-function-memoization :
class Memoize<in T, out R>(val f: (T) -> R) : (T) -> R {
private val values = mutableMapOf<T, R>()
override fun invoke(x: T): R {
return values.getOrPut(x) { f(x) }
}
}
fun <T, R> ((T) -> R).memoize(): (T) -> R = Memoize(this)
I can use it in the implementation class , like this :
class CalculatorSmart : ICalculate {
data class CacheKey(val a: Int, val b: Int)
private val innerCalculate: (CacheKey) -> Int = { key: CacheKey ->
println("cache miss")
key.a * key.b
}.memoize()
override fun multiply(a: Int, b: Int): Int {
return innerCalculate(CacheKey(a, b))
}
}
But it seems it’s hard to apply it in the interface layer.
I wonder if there are any patterns to achieve :
1. Each implementation class ( dumb or smart in this example) doesn’t need to implement its cache .
2. There are no two versions of method ( multiply()
and cachedMultiply()
for example )
3. Client only knows one method of the interface , No matter the client initialize smart or dumb class , the result of the same parameter will be cached and returned.
For example : such scenario is OK
val calSmart: ICalculate = CalculatorSmart()
println(calSmart.multiply(3, 7)) // cache miss
println(calSmart.multiply(3, 7)) // cache hit
val calDumb: ICalculate = CalculatorDumb()
println(calDumb.multiply(3, 7)) // cache miss
println(calDumb.multiply(3, 7)) // cache hit
It will work like Spring’s method cache . but I hope there will be a kotlin-idiomatic style , maybe more functional , just like the memoization pattern above .
Is there any idea ?
Thanks.therealbluepandabear
09/22/2021, 11:55 PMfun String.checkIfShuffledVersionOfAns(ans: String): Boolean {
val listOfChars = this.toCharArray()
val shuffledListOfStrings = mutableListOf<String>()
var iterations = 0
while (iterations < 100000) {
listOfChars.shuffle()
if (!shuffledListOfStrings.distinct().contains(listOfChars.concatToString())) {
shuffledListOfStrings.add(listOfChars.concatToString())
}
iterations++
}
for (string in shuffledListOfStrings.distinct()) {
if (string == this) return true
}
return false
}
louiscad
09/24/2021, 9:56 AMsealed interface
or sealed class
.
What would you pick? Any reason beyond personal preference?
1️⃣ Here's with `interface`:
sealed interface AudioFocus {
object Gain : AudioFocus
sealed interface Loss : AudioFocus {
companion object : Loss
sealed interface Transient : Loss {
companion object : Transient
object CanDuck : Transient
}
}
}
2️⃣ Here's with `class`:
sealed class AudioFocus {
object Gain : AudioFocus()
sealed class Loss : AudioFocus() {
companion object : Loss()
sealed class Transient : Loss() {
companion object : Transient()
object CanDuck : Transient()
}
}
}
Dipendra Singh
09/28/2021, 8:47 PMfun getStreetNameByStreetId(id: String): String {
val query = Query()
query.fields().include("name")
query.addCriteria(Criteria.where("_id").`is`(id))
var streetName = ""
mongoTemplate.executeQuery(
query, STREET_COLLECTION
) { document: Document ->
streetName = document.getValue("name").toString()
}
return streetName
}
Michael Böiers
09/29/2021, 11:17 AM(1..n).asSequence()
and it’s really annoying that you always have to clutter the code with the asSequence()
call to make it lazy (read: perform well). EDIT: Yes, that came across the wrong way … lazy evaluation isn’t always better. 🙂Ben Madore
09/30/2021, 5:48 PMclass MyFoo(
val title: String,
val client: Foo = (some default)
) {...}
I want to provide a default value of Foo when if it’s not provided, but it’s nontrivial to create a valid instance, and requires storing an instance variable e.g.
val x = Bar()
client = Foo.builder().bar(x).baz(Baz.builder().bar(x).build()).build()
i’m struggling to figure out if this is possible with initializer / secondary constructors, without having to make client
a nullable var
.jimn
10/11/2021, 3:58 PMval bolCache: MutableMap<String, SoftReference<Pai2<RowVec, String>>> = WeakHashMap(0)
Jonathan Mew
10/11/2021, 4:29 PM@Suppress("UNCHECKED_CAST")
fun <IdType> createWidgetFactory(cls: KClass<out IdType>): WidgetFactory<IdType> =
when (cls) {
IdA::class -> WidgetFactoryA() as WidgetFactory<IdType>
IdB::class -> WidgetFactoryB() as WidgetFactory<IdType>
else -> throw UnsupportedOperationException("Unknown WidgetFactory type!")
}
marcinmoskala
10/18/2021, 5:04 PMmyanmarking
10/21/2021, 3:22 PMfun addChatHeaders(itemList: List<ChatMessage>): List<HelpCenterChatItem> {
return buildList {
itemList.forEachIndexed { index, item ->
val current: ChatMessage = item
val previous: ChatMessage? = itemList.getOrNull(index - 1)
if (previous == null || (previous.date.dayOfYear != current.date.dayOfYear)) {
add(
HelpCenterChatItem.HeaderDate(
dateFormatter.format(
current.date,
DatePattern.ISO_DAY_MONTH_YEAR_SLASHED
)
)
)
}
add(current)
}
}
}
jwass
10/27/2021, 1:56 PMsealed class Resolvable<T>
class Resolved<T>(val value: T, val pk: Long) : Resolvable<T>()
class Unresolved<T>(val value: T) : Resolvable<T>() {
fun resolved(pk: Long) = Resolved(value, pk)
}
Now I want to take a Collection<Resolvable<ItemIdentifier>>
and filter only unresolved ones, into a Collection<Unresolved<ItemIdentifier>>
.
This works:
val x : Collection<Unresolved<ItemIdentifier>> = itemIdentifiers.mapNotNull { when(it) {is Unresolved -> it else -> null }}
But I wonder if there's a more idiomatic way to do it? (type annotation on x
just for clarity).K Merle
10/28/2021, 5:15 PMtherealbluepandabear
10/29/2021, 8:47 AMclass SnackbarUtils {
companion object {
fun makeSnackbar() {
}
}
}
2.
class SnackbarUtils {
fun makeSnackbar() {
}
companion object {
val instance get() = SnackbarUtils()
}
}
3.
class SnackbarUtils {
fun makeSnackbar() {
}
companion object {
val instance = SnackbarUtils()
}
}
hisham bin awiad
10/31/2021, 1:16 PMprivate val empID
get() = (userModelId ?: session.getUserModelId().toSafetyString()).toSafetyString()
private val empID2 by lazy { (userModelId ?: session.getUserModelId().toSafetyString()).toSafetyString() }
ivano
11/05/2021, 1:24 PMLastExceed
11/09/2021, 5:44 PMfun main() {
val root = Thing(null, 0).apply {
addChild(1) {
addChild(2)
addChild(3) {
addChild(4)
}
}
addChild(5)
}
root.printTree()
}
abstract class Nestable(
val parent: Nestable?
) {
val children = mutableListOf<Nestable>()
}
class Thing(
parent: Thing?,
val number: Int
) : Nestable(parent) {
init {
parent?.children?.add(this)
}
fun addChild(
number: Int,
block: Nestable.() -> Unit = {}
) = Thing(this, number).run(block)
fun printTree(indentation: Int = 0) {
println(" ".repeat(indentation) + number)
children.forEach {
(it as? Thing)?.printTree(indentation + 1)
}
}
}
expected output:
0
1
2
3
4
5
actual output:
0
1
2
3
4
5
find the bug >:)Colton Idle
11/16/2021, 5:24 PMpeople.addAll(
getAllPeople().map { Pair(it.first.orEmpty(), it.last.orEmpty()) }
)
I basically have a variable called people which is a Pair<>, and then I have the return of getAllPeople which is a Person.Colton Idle
11/16/2021, 5:24 PMpeople.addAll(
getAllPeople().map { Pair(it.first.orEmpty(), it.last.orEmpty()) }
)
I basically have a variable called people which is a Pair<>, and then I have the return of getAllPeople which is a Person.Paul Griffith
11/16/2021, 5:29 PMgetAllPeople()
only ever returns a 2 element list?getAllPeople()
returns List<Pair<String, String>>
and you want people
to be a List<Person>
?people
entirely in the map
call:
val people = getAllPeople().map { it.first to it.last }
Colton Idle
11/16/2021, 5:34 PMPaul Griffith
11/16/2021, 5:35 PMJoffrey
11/16/2021, 5:52 PMI basically have a variable called people which is a Pair<>, and then I have the return of getAllPeople which is a Person.You mean lists of those things, right?
Paul Griffith
11/16/2021, 5:54 PMwbertan
11/16/2021, 5:56 PMdata class People(val firstName: String?, val lastName: String?)
fun getAllPeople(): List<People> = emptyList()
fun asas() {
val people = mutableListOf<Pair<String, String>>()
// people.addAll(
// getAllPeople().map { Pair(it.firstName.orEmpty(), it.lastName.orEmpty()) }
// )
getAllPeople()
.map { it.firstName.orEmpty() to it.lastName.orEmpty() }
.let(people::addAll)
}
For me the reason would be to read first what is happening first, so basically getAllPeople
, then map
, the people.ddAll
.
But I would try to avoid the mutable list anyway, which would make it nicer to read from the begin.
Anyway, my only suggestion here would be if you could potentially avoid mutability and perhaps can use immutable data there?
Also what @Paul Griffith said above.Klitos Kyriacou
11/16/2021, 8:54 PMto
infix function to create the pair. The word "to" implies a key-value relationship. First name does not map to surname; it's just a pair of names. Therefore I would use Pair(firstName, lastName) even though it's slightly longer. It's more readable.rook
11/17/2021, 4:48 PMgetAllPeople().mapTo(people){...}
Colton Idle
11/17/2021, 9:58 PMJoffrey
11/17/2021, 10:01 PMval mappedList = sourceList.map { ... }
is preferable over creating a mutable list first and then using mapTo
Pair
. It would seem better to make the properties of Person
non nullable in the first place, or to create an equivalent data class with non-nullable fields if you really need the current Person
classPaul Griffith
11/17/2021, 10:03 PMmap
should be used to apply it. mapTo
is useful if, say, you have a collection with some elements already (that you can't fit into your starting collection) or something like that, but in the problem described, you don't need (and should avoid) creating the list and then populating it in two stepsColton Idle
11/17/2021, 10:08 PMJoffrey
11/17/2021, 10:11 PMPair
stuff then. The mapTo
vs map
still holds, though. In the case you mention, you should use map
.Colton Idle
11/17/2021, 10:18 PMJoffrey
11/17/2021, 10:30 PMmapTo
is what should be used instead to avoid an extra list. But our point was that if you don't already have a mutable list, you should probably not create a mutable list at all and just use the result of map directly