igor.wojda
01/25/2018, 1:10 PMvar appNotifications by Delegates.observable(listOf<AppNotification>()) {
_, _, _ -> notifyDataSetChanged()
}
After
var appNotifications by Delegates.observable(listOf<AppNotification>()) {
notifyDataSetChanged()
}
jkbbwr
01/28/2018, 2:43 AMbenleggiero
01/28/2018, 2:54 AM?.
operator shouldn’t be required when we’ve already verified that we’re not working with a `null`value.
For instance:
// v This proposal focuses on this operator
val isMac1 = System.getProperty("os.name")?.toLowerCase()?.startsWith("mac") ?: false
val osName = System.getProperty("os.name")
val isMac2 = if (osName != null) {
osName.toLowerCase().startsWith("mac")
} else {
false
}
val isMac3 = System.getProperty("os.name")?.let { it.toLowerCase().startsWith("mac") } ?: false
Here, to get the value of isMac1
, System.getProperty("os.name")
returns a String?
, and we used a ?.
to handle that. After this operation, we call .toLowerCase()
(which returns a String
). However, to chain another call (in this case, startsWith("mac")
after that, we need to use a ?.
operator. This baffles me, since toLowerCase()
never returns null
, and we can safely assume it was not successfully called on a null
object, why does the language require that I use a ?.
operator?
To highlight why this baffles me, I use another value, isMac2
. The steps to create this are, in my head, identical to the previous. I get the system property, then if it’s not null
, I check to see if its lower-case form starts with "mac"
. If the property was null
after all, I use false
. Here, toLowerCase()
did not require a ?.
operator because the compiler inferred that it was unnecessary since we already did a null
check. To make isMac1
, in my head, we’ve done the same thing, so the same inference should be made.
Just for completion, I included another way to accomplish this with isMac3
. I get the system property. If it’s not null
, the let
block is entered, and its lower-case form is checked to see if it starts with "mac"
. If that property was null
, then false
is used. Again, no ?.
operator is necessary to use toLowerCase()
, since we already know nothing here is null
so long as the system property isn’t.
Summary:
If we’re chaining function calls and know for sure that we wouldn’t’ve gotten this far if some ?.
had returned null
, then further uses of ?.
should only be required on functions that return an optional/nullable type.kevinmost
01/28/2018, 3:18 AM?
that will be invoked even if the receiver is null
. For example, System.getProperty("os.name")?.toLowerCase().isNullOrEmpty()
, and a distinction must be made if you want that function to execute no matter what, or only when the receiver is non-null
Pavlo Liapota
01/28/2018, 8:14 PMkirillrakhman
01/29/2018, 12:29 PMgildor
01/31/2018, 5:29 PMkevinmost
02/01/2018, 1:50 PM[action] for [variable] in [collection]
is more readable than [collection].map { [variable] -> [action] }
. The latter reads left to right perfectly. For the former, you need to read the whole thing to get context on any of it. And it requires special syntaxianbrandt
02/06/2018, 12:11 AMvar i = 0i
for integers then?", I'll quote David Sedaris, and say that hopefully we can all, "...denounce the very idea as grotesque, and unrealistic." 😉)
var bool = false // Boolean
var b = 0b // Byte. Does not compile. Has to be "= 0.toByte()", or "var b: Byte = 0".
var c = 'c' // Char
var s = 0s // Short. As with Byte, does not compile.
var i = 0 // Int
var l = 0L // Long. Lowercase 'l' not supported.
var f = 0.0f // Float. 'F' also supported.
var d = 0.0d // Double. Does not compile, as 'd/D' not supported.
ilya.gorbunov
02/06/2018, 12:50 AM1b
can be confused with hexadecimal literalgildor
02/06/2018, 3:05 AMmisko
02/06/2018, 10:20 AMclass Json {
val map : HashMap<String, Any> = HashMap()
}
inline operator fun <V> Json.set(key: String, value: V) {
this.map[key] = value as Any // this is not of importance
}
fun obj(builder: Json.()->Unit): Json {
val obj = Json()
builder.invoke(obj)
return obj
}
fun main(args: Array<String>) {
obj {
set("1", 1) // this is ok
this["2"] = 2 // this is ok
["3"] = 3 // this is not - Kotlin: Unsupported [Collection literals outside of annotation]
// - Kotlin: Variable expected
}
}
karelpeeters
02/06/2018, 11:39 AM- other
and in other
also work when leaving out this
?karelpeeters
02/06/2018, 5:29 PMy
for bytes? I skimmed the linked JDK proposal, couldn't really find any justification there either.benleggiero
02/09/2018, 2:56 AMigor.wojda
02/16/2018, 4:19 PMemltyList()
(…Set/Map) top-level functions, and I wonder shouldn’t there be an equivalent like emptyMutableList()
?jw
02/16/2018, 4:25 PMemptyList
returns a singleton... semantics you shouldn't match with an emptyMutableList
natpryce
02/16/2018, 4:37 PMbenleggiero
02/19/2018, 4:21 AMimport Foo.*
import Bar.*
enum class Foo {
a,
b,
c
}
enum class Bar {
a,
b,
c
}
fun translate(x: Foo): Bar = when (x) {
b -> a
a -> b
c -> c
}
val fooBar = translate(a)
Error:(21, 30) Kotlin: 'when' expression must be exhaustive, add necessary 'a', 'b', 'c' branches or 'else' branch instead
Error:(22, 5) Kotlin: Unresolved reference: b
Error:(22, 10) Kotlin: Unresolved reference: a
Error:(23, 5) Kotlin: Unresolved reference: a
Error:(23, 10) Kotlin: Unresolved reference: b
Error:(24, 5) Kotlin: Unresolved reference: c
Error:(24, 10) Kotlin: Unresolved reference: c
Error:(29, 24) Kotlin: Unresolved reference: a
And the only way to resolve these is to say Foo.a
or Bar.c
everwhere a member of either is needed. With proper IME support, .a
and .c
would do the job every time without ambiguity.mikehearn
02/19/2018, 4:44 PMgroostav
02/24/2018, 9:05 PMPere Casafont
02/26/2018, 3:06 AMcedric
02/26/2018, 4:02 AMval
is not what C++' const
isPere Casafont
02/26/2018, 8:46 AMPere Casafont
03/03/2018, 6:24 PMAregev2
03/05/2018, 5:51 AMkarelpeeters
03/11/2018, 12:39 AMtypealias Complicated<T, E> = List<Pair<T, List<E>>
sanf0rd
03/12/2018, 2:52 PMbenleggiero
03/12/2018, 3:25 PMdiesieben07
03/12/2018, 3:46 PMwhen
?