https://kotlinlang.org logo
Title
r

ribesg

08/27/2019, 2:35 PM
Why can’t I pass a value of type
Map<String, String?>
for a parameter requiring type
Map<Any?, *>
?
b

Big Chungus

08/27/2019, 2:35 PM
String extends Any whereas String? extends Any?
In short Any does NOT extend Any?
r

ribesg

08/27/2019, 2:36 PM
I can’t pass
Map<String?, String?>
either
b

Big Chungus

08/27/2019, 2:36 PM
Ah
Your parameter def needs to be
Map<out Any?, *>
☝️ 1
r

ribesg

08/27/2019, 2:37 PM
Well it’s not my function
b

Big Chungus

08/27/2019, 2:37 PM
Otherwise it'll require you to cast to Any, rather than allowing extensions
Then cast your map to required type
r

ribesg

08/27/2019, 2:37 PM
Yeah a forced cast should not cause any problem in this specific case
The function I called is defined as
@kotlinx.cinterop.ObjCMethod public open external fun setMetadata(metadata: kotlin.collections.Map<kotlin.Any?, *>): kotlin.Unit
b

Big Chungus

08/27/2019, 2:38 PM
It's an open function. I'd override it with modified def
See if the compiler complains
t

thana

08/27/2019, 2:39 PM
generics are invariant i.e. String
is
Any but List<String>
!is
List<Any>
r

ribesg

08/27/2019, 2:39 PM
I’m calling this only once so I’ll go with a forced cast
s

streetsofboston

08/27/2019, 2:40 PM
@thana A List<String> is a List<Any>, since list is defined as
List<out T>
5
But for a Map, the key is an invariant, not a covariant:
Map<K, out V>
t

thana

08/27/2019, 2:42 PM
Oh yes, you are right i forgot about declaration-site varrance in kotlin and just copied the standard java example over
s

streetsofboston

08/27/2019, 2:43 PM
(if it weren’t for the
keys
and
entries
properties, Map could have been `Map<in K, out V>`….)
☝️ 1
l

louiscad

08/28/2019, 8:21 AM
Answering the initial question: Because if you pass it to
Map<Any?, *>
, you would then be able to put anything in the map, be it mutable under the hood.