How to get KClass<List<String>> type from List<String> in kotlin - kotlin

I'm having problem with Kotlin poet PropertySpec object. Because i can't provide List<String> to the PropertySpec builder.
Help please.
PropertySpec.builder("services", List<String>::class.asTypeName()).build()

To add generics types info you need to use parameterizedBy for example
val stringList = ClassName("kotlin.collections", "List").parameterizedBy(String::class.asTypeName())

Related

Where is this kotlin expression described in the documentation?

I have this kotlin function, and I undersatand that the expression : row.map(Char::digitToInt), converts a Char into an Int.
What I need, is more explanation regarding Char::digitToInt.
How can I relate the use of :: in the kotlin documentation?
Thank's in advance for your reply.
private fun parseInput(input: List<String>): Array<IntArray> =
input.map { row: String ->
row.map(Char::digitToInt).toIntArray()
}.toTypedArray()
As stated in the docs this is a class reference:
Class References: The most basic reflection feature is getting the
runtime reference to a Kotlin class. To obtain the reference to a
statically known Kotlin class, you can use the class literal syntax:
val c = TestClass::class //The reference is a value of type KClass.
Note that a Kotlin class reference is not the same as a Java class
reference. To obtain a Java class reference, use the .java property on
a KClass instance.
It’s also the syntax for method references as in this simple example:
myList.forEach(::println)
It refers to println defined in Kotlin Standard library.

Usage of Kotlin typealias for Map.Entry in Map

In Kotlin, it's possible to define typealias for classes, hence, also for Map<K,V>. Let's say, that I have the following:
typealias MyMap = Map<String, String>
But, what if I'd like to name the map entry as well, like this:
typealias MyEntry = Map.Entry<String, String>
typealias MyMap = Map<MyEntry> // error
However, Kotlin does not accept this, since Map<K,V> requires a type for the key and the value. Is such a thing as shown above possible?
No. This has nothing to do with typealias, rather how to declare generic types.
Map interface requires two type parameters and you must provide both otherwise you get the error, If you want to use a Map which is parameterized over its entry rather than Key, Value then you can define your own Map Type.
In the above case when you do Map<MyEntry>, you want the language to take the single type parameter (MyEntry) that you provide and extract its two components(String and String) and then use those two components as two different type parameters for the Map. Sorry you are asking too much.
MyEntry is a single type and it can only be used as such. Following is an example of that
typealias MyMap = Map<MyEntry, String>
The real answer is mightyWOZ's, but maybe this tip helps as well:
You can still use generics in typealiases to forward one of the arguments:
typealias StringMap<T> = Map<String, T>

How to use Parceler with ArrayList<Map<String, String>>?

I'm trying to use Parceler to transfer variable of ArrayList>, but it always give error when running, just link intent.putParcelableArrayListExtra("votedetail", arrlist);. Searched and found no example, how to use it? Thank you in advance.
Please take a look at the method's signature on Android Developer docs:
Intent putParcelableArrayListExtra (String name, ArrayList<? extends Parcelable> value)
The objects in the ArrayList have to be Parcelables.
As far as I know, Android SDK implementations of Map<K,V> (HashMap, SortedMap, etc) do not implement Parcelable. You will have to write your own implementation which will also be Parcelable.
B0Andrew, Thank you for your help. I found the answer at last. Using putParcelableArrayList to do it. First wrap the
"Arraylist<Map<String, String>>"
to become Arraylist(new one Arraylist, then add the variable), then I can use putParcelableArrayList to transfer the data.
Parceler is a library for serializing Parcelable objects. There is no need to use putParcelableArrayListExtra(), just use putParcelable():
List<Map<String, String>> value = new ArrayList<>();
// Fill out List
intent.putParcelable("votedetail", Parcels.wrap(value));
And you may deserialize in the onCreate of the receiving activity:
List<Map<String, String>> value = intent.getParcelableExtra("votedetail");
You can find examples on how to use it directly on the website: http://parceler.org/

Kotlin-allopen plugin + #JvmField on a val not final enough

I am testing a new kotlin-allopen and kotlin-spring plugins under Kotlin 1.0.6.
In one of my #Transactional-annotated classes I have a field:
#JvmField val foo = null
When I try to build the project, I get:
Error:(45, 5) Kotlin: JvmField can only be applied to final property
Is there any proper way of dealing with this? My real-life code needed #JvmField because of the JUnit's #Rule. Managed to "solve" the problem by removing a #JvmField and annotating a getter instead. Not sure if a bug or a feature.
I got the official solution.
In such case, finality provided by val is not enough. It turns out you need explicitly add final keyword there and this is not considered a bug.
#JvmField final val foo = null

Kotlin JUnit Rules

In Kotlin M13, this was an acceptable way to create a JUnit rule:
#Rule #publicField val temp = TemporaryFolder()
Now that #publicField has been deprecated, how else can this be achieved? The IDE hint suggests replacing #publicField with lateinit, but lateinit val's are no longer allowed, and I'm not sure this would help even if they were.
The answer as of Kotlin 1.0 is as follows:
#Rule #JvmField val temp = TemporaryFolder()
#JvmField exposes the backing field with the same visibility as the property, ergo a public field for the JUnit rule to use.
If anyone stumble's on this. I believe the approach with JJunit5 would be using #TempDir.
https://junit.org/junit5/docs/5.4.2/api/org/junit/jupiter/api/io/TempDir.html
If you would need share the TempDir with tests, it must be a static property of the class. Static for java or within a companion Object for Kotlin
Just guessing, but the following might work (with var):
#Rule lateinit var temp = TemporaryFolder()
I would try asking at kotlin's slack http://t.co/xpQXUKaDvP
Currently it's the fastest way to fix anything.