2022/03/12

[kotlin] Windowsでコンパイル

最近、話が長くなっていかん。
なので、先にまとめた内容を書いて、あとにだらだらと書き綴ろう。

 

まとめ

  • kotlinc を初回実行するときには結構な量のダウンロードが行われる
  • Kotlin の Array<E> は配列、ArrayList<E> は List<E> の仲間
  • ArrayList の初期値ありは arrayListOf() で作ればよい
  • ArrayList<Byte> を ByteArray に変換するには .toByteArray() を使えばよさそうだ

 


おはなし

 

Android で Kotlin の勉強しつつやっているのだが、勉強のために Android アプリを作るのはめんどくさい。
PC 上で動かせるようにしよう。

Kotlin command-line compiler | Kotlin
https://kotlinlang.org/docs/command-line.html

GitHub から一式をダウンロード(今の最新は 1.6.10) して、zip を展開。
あんまりファイルが大きくなくて良かった。

Hello World の ktファイルを作ってコンパイル。

>bin\kotlinc.bat test.kt

うわー、ダウンロードが始まった・・・。
しかも結構かかる・・・。

最終的に、 %USERPROFILE%.konan に 1GB くらいダウンロードされた。
JavaScript に対する TypeScript みたいな関係だと思っていたけど、Windowsネイティブなコードを吐くようにしているからだろうか?

まあいい。
深くは考えまい。

なお、コンパイルすると program.exe という実行ファイルができた。


初回だし、次回やるかも分からんので、気になっていることを調べて終わろう。
やりたいのは、Array<Byte> でもらったデータを ByteArray に変換したい、だ。

それぞれ違いはなんじゃ?と調べてみたのだが、

  • ArrayList<Byte> は Javaでいうところの Byte[]
  • ByteArray は Javaでいうところの byte[]

らしい。

java - Difference between ByteArray and Array<Byte> in kotlin - Stack Overflow
https://stackoverflow.com/questions/9457942/difference-between-bytearray-and-arraybyte-in-kotlin

もしかしたら ArrayList<Byte> かもしれんが、ともかくオブジェクトかプリミティブ型かの違いが大きいということだろう。
Kotlin は「[]」みたいな配列の作り方ではなく「Array<T>」のような形でしか書けないので、T がプリミティブ型だと効率が悪いだろうってことで ByteArray 型が別に用意されているんだと思う。

 

変換したい背景をもう少し話すと、React Native 側のデータが Uint8Array 型で、それを Android 側で処理することになった。
React Native と Android の型は異なるので、この型はこうなるというマッピングがある。

Argument Types
https://reactnative.dev/docs/native-modules-android#argument-types

JavaScript の Uint8Array は Array だろうから、Java だと ReadableArray というものになる。
ReadableArray は React Native で提供される型でこうなっている。

react-native/ReadableArray.java at main · facebook/react-native
https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableArray.java

この中で一番 ByteArray に近そうなのはこれだろう。

ArrayList<Object> toArrayList();

・・・と思ったのだが、ArrayList<Object> なので ArrayList<Byte> ではない。
これは as で変換できてほしい(願望)。

そして ArrayList<Byte> を ByteArray に変換したい、というところなのだ。
いや、それは正確ではないな。実際にやりたいのはファイル保存なのだ。 ByteArrayInputStream というクラスがあったので ByteArray に変換したいだけであって、InputStream になるなら ByteArray である必要はないし、ファイルに保存できるなら InputStream である必要もない。

ノウハウがないときは近道が分からないから困りますな。


Kotlin の ArrayList には toByteArray() というメソッドがある。
これでいいのかな?

toByteArray - Kotlin Programming Language
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-byte-array.html

 

では、まず ArrayList を作ろう。
・・・書き方が分からん。
Kotlin は ArrayList<T> しかないと思っていたのだが、 Array<T> もあるのか。

Arrays
https://kotlinlang.org/docs/basic-types.html#arrays

Array なら arrayOf() で初期値が作れそうなのだが、 ArrayList は?
そもそも、 Array と ArrayList の違いは何なのか??

 

ArrayList はこんな感じなので、MutableList の仲間。

class ArrayList<E> : MutableList<E>, RandomAccess

class ArrayList<E> : MutableList<E>, RandomAccess, AbstractMutableList<E>

List を Array っぽく使えるようにしただけで、あまり Array と関係はないのだろう。
なので初期化も ArrayList のコンストラクタを使えばよかろう。

 

ArrayList のコンストラクタは 2つ。
空の ArrayList を作るか Collection<E> で初期値を持つか。
Collection に arrayListOf() という関数があるそうだ。

arrayListOf - Kotlin Programming Language
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/array-list-of.html

いやー、これは ArrayList の方にもリンクを貼っておいてほしいよ。わからんよ、探したよ。
全体的に~Of() という関数は ~型 の new関数みたいに作ってあるように見える。

 

01: fun main() {
02:     // val va: ArrayList<Byte> = arrayListOf(1, 2, 3, 253, 254, 255)
03:     val va: ArrayList<Byte> = arrayListOf(1, 2, 3, -3, -2, -1)
04:     val v8: ByteArray = va.toByteArray()
05:     for (v in v8) {
06:         println(v)
07:     }
08: }

>.\program
1
2
3
-3
-2
-1

Java と同じく Byte 型は int8 の範囲なので 128~255 はダメだった。
まあ、問題はそれだけだ。