tim
02/28/2020, 10:44 AMdata class
object from Google's Firestore. I can save my data class (lets call it Parent) to Firestore, but on retrieval it is a HashMap which seems nontrivial to convert back because some values on Parent are themselves data classes:
data class Parent(val id: String, val child1: Child1, ...)
data class Child1(val name: String)
I can't use GCP's DocumentSnapshot.toObject(Parent::java.class) because for that to work, every field on Parent needs to be nullable, and I'd have to recursively create nullable data class intermediaries (i.e., NullableChild1, etc) ... any suggestions on a better approach? I'm new to Kotlin so figure I'm missing something obvious here 🤷
Example code:
// What i'd like to do
fun getFromFirestore(id): Parent {
...
val data = doc.data()
data.toObject(Parent::java.class) // this throws because it needs a 0 argument constructor to unpack the hash map into
}
// Overly complex solution
fun getFromFirestore(id): Parent {
...
val data = doc.data()
data.toObject(NullableParent::java.class) // this throws because it needs a 0 argument constructor to unpack the hash map into
}
data class NullableParent(val id: String?, val child1: Child1?, ...) {
constructor(): this(null, null) // I could also unpack the hash map here but then this constructor gets verbose!
fun toParent(): Parent {
if(id == null || child1 == null...) throw Error("blah")
return Parent(id, child1, ...) // this doesn't work because Child1 doesn't have a 0 argument constructor so I'd have to create a NullableChild now 😢
}
}
iex
02/28/2020, 11:31 AMjbnizet
02/28/2020, 12:09 PMclass ListScope {
internal val items = mutableListOf<BulletedListItem>()
operator fun String.unaryMinus() = items.add(BulletedListItem(this))
}
allowing me to use
list {
- "first item"
- "second item"
}
Am I right to say that it’s impossible to do the same with an extension function of ListScope?
I.e. something like
class ListScope {
internal val items = mutableListOf<BulletedListItem>()
}
operator fun ListScope.String.unaryMinus() = items.add(BulletedListItem(this))
aaverin
02/28/2020, 1:43 PMcopy()
constructor of a data class as a kind of builder, essentially calling it multiple times to re-create an object adding some data inside in a pattern like:
data class TrackingEvent(
val eventType: String = "",
val eventFeature: String = "",
val eventVariant: String = ""
)
fun TrackingEvent.click() = copy(eventType = "click")
fun TrackingEvent.onArticleFromStage(stage: String): TrackingEvent {
return copy(
eventFeature = "article_stage",
eventVariant = "click on article from stage $stage"
)
}
TrackingEvent().click().onArticleFromStage("stage")
On one hand I can understand why creating new object would result in GC cleaning up the old one. On the other hand, we have an immutable class and I think I read somewhere about compiler optimizations on this, not creating a new pointer a memory for properties and rather reusing old pointers?
Am I wrong? Should I bring back builder back from Java days instead if I want similar functionality?Sylvain Patenaude
02/28/2020, 2:46 PMRob Murdock
02/28/2020, 3:44 PMiex
02/28/2020, 5:40 PMfun Date.toCalendar(): Calendar {
val calendar = Calendar.getInstance()
calendar.time = this
return calendar
}
KotlinIsMyFav
02/28/2020, 10:07 PMOrhan Tozan
02/28/2020, 10:27 PMelect
02/28/2020, 10:45 PMptrId = Array(newBufLength) { i -> ptrId.getOrElse(i) { i } }
Chills
02/29/2020, 9:16 AMPere Casafont
02/29/2020, 9:38 AMclass A
inline fun <reified T> A.foo(): T = TODO("Not necessary to implement")
open class B {
val a = A()
inline fun <reified T> foo() = bar { foo() }
fun <T> bar(baz: A.() -> T) = a.baz()
companion object : B()
}
Chills
02/29/2020, 10:05 AMtim
02/29/2020, 12:27 PMmatcher: (x: Any) -> Boolean
. Later when i pass in a lambda for matcher, I have to cast from Any to the concrete type as per blew. Is there a better way to do this?
data class Query(
matcher: (x: Any) -> Boolean
)
...
val query = Query(
matcher: { x: Any? ->
val value = x as Int?
if(value == null || value == 0) false else true
}
)
ageery
02/29/2020, 1:21 PMclass BadTest(val name: String? = null)
val badTestCreator: () -> BadTest = ::BadTest
But that this does work:
class GoodTest(val name: String? = null) {
constructor(): this(name = null)
}
val goodTestCreator: () -> GoodTest = ::GoodTest
Shouldn't there be a no-arg constructor for BadTest
that would satisfy the () -> BadTest
type?Chills
02/29/2020, 1:44 PMageery
02/29/2020, 4:50 PMval xyz: Map<String, (String) -> Unit> = mapOf("abc" to { it -> println(it.length) })
with a suggestion that there is a 'redundant lambda arrow' (the it ->
part in the lambda in the map key).
However, if I remove that portion, I get a 'type inference failed' compile error. The compiler interprets the lambda as () -> ???
rather than (String) -> Unit
. Shouldn't the compiler interpret { println(it.length) }
as satisfying (String) -> Unit
?sksk
02/29/2020, 6:24 PMval list = arrayListOf<Int>()
result in boxed values?Daniel
02/29/2020, 8:09 PMpaddingTop = (paddingTop * factor).toInt()
Maybe an extension function but this seems odd:
private fun Int.fMul(factor: Float) = (this * factor).toInt()
ec
02/29/2020, 9:24 PMval pp = Path.of(System.getProperty("user.dir"),"test.py")
val p = ProcessBuilder("python3", pp.toString())
p.redirectErrorStream(true)
val pr = p.start()
pr.outputStream.close()
while (true) {
if (pr.inputStream.available() < 1)
Thread.sleep(10)
else {
val content = pr.inputStream.bufferedReader().use(BufferedReader::readText)
println(content)
}
}
Python script:
import time
print("ABC")
i = 0
while True:
print("ABC")
i += 1
time.sleep(1)
But nothing gets printed to screen. (Unless I remove the while
part, then it actually prints "ABC" so python path, script path is correct) What is the correct way to do this?Chills
03/01/2020, 6:29 AMMarc Knaup
03/02/2020, 10:23 AM@kotlin.internal.InlineOnly
? (esp. in a Kotlin-only library) 🙂CLOVIS
03/02/2020, 4:33 PMval a: Int by lazy { 5 }
not an interface? Instead they are weird classes that have to have certain methods without specifying an interface...
I would like to write a and
infix function that creates a delegate that combines two others, but I'm afraid that won't be possible because of thisjeggy
03/02/2020, 5:56 PMstackOf("value 1", "value 2")
August Gruneisen
03/02/2020, 10:07 PMdata class Objects(
val objects: List<MyObject>
) {
fun containsFirstProperty(value: String): Boolean {
var itDoes = false
objects.forEach {
if (it.firstProperty == value)
itDoes = true
}
return itDoes
}
}
data class MyObject(
val firstProperty: String,
val secondProperty: String
)
Thanks!gotoOla
03/03/2020, 12:22 PMTmpod
03/03/2020, 5:01 PMuser
03/03/2020, 6:43 PMjames
03/04/2020, 3:58 AM* DatabaseKennelModel
+ dogs: List<DatabaseDogModel>
* DatabaseDogModel
+ name: String
* Kennel
+ dogs: List<Dog>
* Dog
+ name: String
Is there a better way to transform a List<DatabaseKennelModel>
into a List<Kennel>
, than the following:
databaseKennelModelList.map { databaseKennelModel ->
Kennel(
dogs = databaseKennelModel.dogs.map { databaseDogModel ->
Dog(
name = databaseDogModel.name
)
}
)
}
☝️ it works, but I'm wondering is there anything I can do to avoid that nested map
?darkmoon_uk
03/04/2020, 6:36 AMUnit
. Any tricks to achieving this neatly?