しおしお

IntelliJのあれやこれや

Kotlinのチケットを眺めてみて

Kotlinアドベントカレンダーの12/20の記事です。

Kotlinへの要望やバグの管理は、https://youtrack.jetbrains.com/issues/KTで行われているので、その中で私がふんだバグやこれ直してほしいな的なのを幾つかあげています。
これは的なチケットには、vote(+1)をお願いしたいです。。

本当は、vote数が多いのから紹介したかったんだけど、英語力が皆無なので諦めました(´・ω・`)

Callable referenceの問題

パッケージレベル以外の箇所で定義された関数の参照を使用した場合に、関数の型が関数定義とは異なる型となりまともに使えない件。

問題となるコード例:
以下のようにに、クラス内に定義された関数の参照を(Int -> Boolean)なfilter関数に渡すと型が異なるためエラーとなる。

class Hoge {
  
  fun isOdd(x:Int) = x % 2 == 0

  fun hoge() {
    intArray(1, 2, 3).filter(::isOdd)
  }
}

現状、以下のようにパッケージレベルに定義された関数のみ参照渡しが使えない感じである。

fun main(args: Array<String>) {
  intArray(1, 2, 3).filter(::isOdd).forEach { println(it) }
}

fun isOdd(x:Int) = x % 2 == 0

実行時にIllegalAccessErrorが出る問題

呼び出し先のメソッドの引数のクラス(インタフェース)が、呼び出し元から参照出来ない場合にこの問題が発生する。

言葉で説明するのがなかなか難しいので、実際のコード例を・・・

下記のコードの場合、一番最後のmain関数でHoge#hogeで実行時にIllegalAccessErrorが発生する。これは、コンパイル時にメソッドの引数であるBaseInterfaceへのキャストチェック(CHECKCAST)がバイトコードに埋め込まれるために発生していようです。*1

package hoge;

interface BaseInterface {
}

package hoge;

public class Base implements BaseInterface {
}

package hoge;

public class Hoge {
    public static void hoge(BaseInterface base) {
    }
}

fun main(args: Array<String>) {
  Hoge.hoge(Base())
}

関数リテラルからのリターンのサポート

一応、現状でも下のように書けばいけるけど、これじゃめんどくさいしもっと簡単に!的なチケットですね。

// 関数リテラルの型を定義してあげないと、関数リテラル内のreturnはコンパイルエラーになります。
intArray(1, 2, 3).forEach {(it:Int):Unit ->
  if (it == 2) {
    return@forEach
  }
  println(it)
}

IDEプラグインで補完ができない問題

補完できないのはかなりきつい(´・ω・`)

なんでこれ対応出来てないのって思ったけど、Javaみたいに@始まりでもないし候補出すのが難しいんではないか疑惑がある。*2

おわり。(超絶ざつな感じになって申し訳ない感あるm(__)m)

*1:私は、Twitter4JのストリーミングAPIをKotlinから使った場合にこの問題にぶち当たりました

*2:PRしようと思った時期が僕にもあったけど、候補の抽出で悩んで諦めた僕がいる