カテゴリー: プログラミング

型判定とキャスト : kotlin

型判定とキャスト

is演算子と!演算子による型判定

※これis演算子と否定の!演算子の組み合わせだから、こういう表現の方が正しいような気がするけれども、どうだろうか(´・ω・`)?

is演算子またはその否定形式である!isを使用して、実行時にオブジェクトが特定の型に準拠しているかどうかを確認できます:

if (obj is String) {
  print(obj.length)
}

if (obj !is String) { // !(obj is String)と同じです。
  print("Not a String")
}
else {
  print(obj.length)
}

スマートキャスト

Kotlinでは多くの場合、キャスト演算子を明示的に使用する必要はありません。コンパイラは不変の値に対するis演算子の使用を探知し、必要に応じて(安全な)キャストを自動的に挿入するからです:

fun demo(x: Any) {
  if (x is String) {
    print(x.length) // xは自動的にStringにキャストされます。
  }
}

コンパイラは、否定判定の結果がReturnになる場合にキャストが安全になること(キャストが発生しないこと?)を理解するほどに賢いです: ←※いろんな翻訳サイトを使ってもいまいち翻訳しきれなかったのでちょっと超訳(´・ω・`)シドニィ

if (x !is String) return
  print(x.length) // xは自動的にStringにキャストされます。

また&&および||演算子の右側でも:

  // `||`の右側でxは自動的に文字列にキャストされます。…(1)(2)
  if (x !is String || x.length == 0) return

  // `&&`の右側でxは自動的に文字列にキャストされます。…(2)
  // 同上
  if (x is String && x.length > 0)
      print(x.length) // xは自動的にStringにキャストされます。

(1)原文に即して翻訳したけれども、コンパイラはis判定でtrue(または!is判定でfalse)で、後の行でその変数を使用する場合にのみ即時キャストするのか、使用直前でキャストするのかでここの文言が変わって来るような気がする。そういう意味合いにおいてはいつキャストされるかということを明示した方がいいのではなかろうか?
(2)stringじゃなくてStringだな。ここの二箇所だけstringになってる。どうでもいいけどw

このようなスマートキャストは、when式とwhileループでも機能します。:

when (x) {
  is Int -> print(x + 1)
  is String -> print(x.length + 1)
  is IntArray -> print(x.sum())
}

コンパイラが判定時と実際の使用時の間で変数が不変であることを保証できない場合、スマートキャストは機能しないことに注意してください。より具体的には、スマートキャストは次のルールに従って適用されます。:

valローカル変数 - 常時;
valプロパティ - プロパティがprivateまたはinternalである場合、またはプロパティが宣言されているのと同じモジュールで判定が実行される場合。スマートキャストは、openのついた継承可能なプロパティまたはカスタムゲッターがあるプロパティには適用されません。
varローカル変数 - 変数が判定時と実際の使用時の間で変更されておらず、それを変更するラムダに捕捉されていない場合。
※Kotlinのラムダ式はラムダ式の中から、外側の変数の値を変更することができ、これを捕捉できると表現する模様。まあ詰まるところ変更されない限りということだろうか。https://maku77.github.io/kotlin/basic/lambda.html
varプロパティ- 不可。(このvarプロパティは他のコードによっていつでも変更されうる為。)


"アンセーフ(安全ではない)"キャスト演算子

通常、キャストが不可能な場合、キャスト演算子は例外をスローします。したがって、私たちはそれをアンセーフ(安全ではない)と呼びます。 Kotlinでの安全ではないキャストは、中置演算子 asによって行われます("演算子の優先順位"を参照)。:

val x: String = y as String

この型はnull許容ではないため、nullをStringにキャストできないことに注意してください。つまり、yがnullの場合、上記のコードは例外をスローします。 Javaキャストのセマンティクスに一致させるには、キャストの右側にnull許容型が必要です。
※キャストの右側だけじゃなくて左側の宣言の型にも必要なんじゃ? それとも型の右側という意味?

val x: String? = y as String?

"セーフ(安全な)"(null許容)キャスト演算子

例外がスローされるのを避けるために、失敗時にnullを返すセーフキャスト演算子as?を使用できます。

val x: String? = y as? String

as?の右側が非null型の文字列であることに関わらず、キャストの結果はnull許容型です。

\コットリ~ン/

ガチで勉強する気も何かを作る予定もないものの、今年は余りにも何もしなかったので、現実逃避的にkotlinを触り始めた(´・ω・`)

まあ中古ゲームや漫画の消化の傍らにkotlin koansをやったり、その延長線上でkotlinの解説ページを眺めたり翻訳したりしてるだけだけど。
(実際のところ、翻訳はほぼほぼごっぐる先生の翻訳である(ノ∀`))

記憶力が低いのか新しいことを勉強すると、前にやっていたことのほとんどを忘れてしまうたちなので、適当にエントリ化して記録しておこう("・ω・゙)トシダシネ


IntelliJ IDEA

取り敢えずIDEはIntelliJ IDEAに。
Android Studioでも触れるようだけれども、まあKotlin Nativeとかも試してみたいので、IntelliJ IDEAの方にしておいた。

スニペットコードを試す分には何の問題もなかったが、コンソールアプリケーションを実行しようとした時に以下のようなエラーが発生。

java.lang.NoClassDefFoundError: org/jetbrains/kotlin/cli/common/PropertiesKt at org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper.apply(KotlinPluginWrapper.kt:82)

なんかようわからんけど、Project JDKのバージョンの問題だかどうとか。
最初はProject JDKを15にしていて駄目だったから、取り敢えずcorretto 1.8だかの古いのを落として来て設定したんだったかな…?

最初は[Build, Execution, Deployment]-[Build Toos]-[Compiler]-[Java Compiler]の[Project bytecode version]を変更すればいいのかと思ったがそうではなかったような…あんまり細かいことは覚えていない(ノ∀`)

何はともあれ、[Build, Execution, Deployment]-[Build Toos]-[Build Tools]-[Gradle]の[Gradle JVM]を落としてきた古いやつに変えたら上手くビルド出来るようになったんだったか…確か……

この辺のJDKとかのエラーってもっとこうインテリジェントにというか、IDE側で検知して解決策を提示してくれるように出来ないのであろうか(´・ω・`)?


Kotlin Koans

問題集みたいなプロジェクトパックのKotlin KoansというのがあるのでEduToolプラグインを入れてやり始めてみた。

koanってなんだろって思ったら、元ネタは禅問答の公案らしい。

公案(こうあん)とは、禅宗で修行僧が参究する課題である。日本では昔から1千7百則とも言われ、法身、機関、言詮、難透などに大別されるが、その他に様々な課題がある。内容はいわゆる禅問答であって、にわかに要領を得ず、解答があるかすら不明なものである。有名な公案として「隻手の声」、「狗子仏性」、「祖師西来意」などがある。

 例: 両手を叩くと音がする。では片手の音とはなんだろう。(隻手の声)
公案


ちょこっとした問題文とコードが書いてあって、それを修正してチェックボタンを押して正誤判定するみたいな感じ……

…なんだけど、これって誰を対象にしてるんだがよくわからないw
ごっぐるのAndroid Developersもそうなんだけど、どのくらいのレベルの人に何を教えようとしているのかがよくわからないw

元々のkotlinの基礎知識がないと各問題にリンクされている参考ページを読んだだけでは、すぐに何をしていいかわからなくなると思う。

少なからず、kotlinのサイトのGetting Startedを上から順にやっていって、Koansのところに辿り着いた段階の俺氏にはさっぽろわっかない状態だった(´・ω・`)

結局色々なサイトや日本語リファレンスをそれなりに読みながらじゃないと理解は進まないと思った。

日本語リファレンスも途中までしか訳されていなくて、しかもなんか新しいバージョンの英語リファレンスとかもあったりするので、プログラミング界の永遠のnewbeeである俺氏は混乱せざるを得ない状況である(´・ω・`)


「Named arguments」の回答って、"Make the function joinOptions() return the list in a JSON format (e.g., "[a, b, c]") by specifying only two arguments."なので2つの引数しか許さないのかなと思ったけれども、

fun joinOptions(options: Collection<String>) =
        options.joinToString(
                ", ",
                "[",
                "]"
                )

なんて形で3つの引数を渡してもパスしちゃうのは何故なんだぜ(´・ω・`)?
問題文として条件は出してるものの、システム的なチェックはしてないのかな?

単純にdiffとかしてるんじゃないのか…?
failing unit testを使ってるとか書いてあるな…


全然関係ないけれども、IntelliJ IDEAはコード表示部分以外のフォントサイズを簡単に変更出来るので、老眼等で小さい字が読みにくくなり、かといって馬鹿でかいディスプレイを入手できない俺氏にとっては嬉しいユーザービリティである(・∀・)


一年前くらいにもちょっと手を出してすぐ放置してしまったので、今回もそうなる可能性は高い(・∀・)

つーかこんなことをしていないで、Unity+C#の続きをやったり、真面目に仕事を探さないといかんな(ノ∀`)

取り敢えず、GCP側に移行出来た模様(´・ω・`)

さくらVPSからgTLDドメイン転出用のオースコードが届いたので、移行作業を続行。
【さくら→Google移行作戦 前半】ドメイン移管編

Google Domain 1400+112(税)=1512円だった。さくらVPSは税込み1852円なので340円差か。働いていたら誤差のレベルだな。というか働いていたらさくらVPSからGCPの無料運用に移行することもなかったか(ノ∀`)


移行前に最新データのバックアップを忘れる(ノ∀`)

深いことを考えずに作業した為に、元ブログ側の管理ページに入れなくなる(ノ∀`)
加えてどっちのページが表示されているのかわからなくなるw
致し方なく、データ移行処理後に追加した2エントリは手動で移し替えたw

ドメインとGCPのIPアドレスが結びついている状態で何故かhttps://mole-kingdom.com/idx.htmlのページがURL指定で表示されたのは謎(´・ω・`)?
さくらVPSのインスタンスを止めたら表示されなくなったので、あっち側のページなのは間違いないのだが。なんだろう? キャッシュ?
今はデータを移行したので表示されて当然なんだけども


language-pack-ja

従来の方法でubuntuの文字化けが直らなかったので、以下のエントリに従ってaptでインストールしたら文字化けが解消された。もしかしたらlanguage-pack-jaが入ってなかっただけなのかな?

参考:
Ubuntuのデフォルトロケールを変更する


wp-cli

何故か移行先でDuplicatorプラグインが削除出来なかった(´・ω・`)
正解に言えば停止しようとすると技術的問題がどうとかというエラーが出て、先に進めない。

プラグインフォルダから削除するだけでもいいが、dbの中にゴミが残るとかどうとかいう噂を読み、wp-cliを入れて処理した。いきなりuninstallは出来なかったので先にdeactivateしてからuninstallした。

その後、WordPressのプラグインページに行ったら、まだDuplicatorは何故か存在しつづけていたが、その状態で削除をクリックしたら、無事に一覧から消えた。色々と謎が残る(´・ω・`)

参考:
WP-CLIの使い方
wp-cli コマンド一覧


xlrd

Pythonでexcelファイルを触る為のライブラリ xlrdを使ってみた。なんというか、まあ、ふーん(・∀・)と言った感じである。

パスが上手く通らなくて困ったが、Windowsだと全部"/"でええんかΣ(゚∀゚;)

参考:
Excel読み込み (xlrd)
Windowsのパスがうまく指定\表示できない問題 in Python
パワポエンジニアの憂鬱を軽減する誤字/表記揺れ検出ツールを作った物語


Google DriveでのOCR

なんやかんやで出来るようになったが、何をどうして上手く行ったのかよくわかってない(ノ∀`)
参考にしたコードはWindows向けではなかったからか、ちょっとはまった。Spyder3のフォルダ内で作業していたのが悪かったのかもしれない。

取り敢えず、そもそもoauth2clientが入ってなかったので動かなかったみたい(ノ∀`)
pipでinstallした。

正しい対処法かわからないが、CLIENT_SECRET_FILEの値に絶対パスを追加したり、credential_pathのところを絶対パスに変えて、Anconda Promptでの実行にもパスを追加した。

全く詳しいことを覚えていないが、なんかクレデンシャルがない状態の時にOCR対象のファイル名を引数に指定せずに実行したら、クレデンシャルがとれたような……

その後で改めてファイル名も指定して実行したら、無事にOCRが動いたような……( ´・ω・)ジシンガナイ

固有表現抽出APIにはまだ投げていない(ノ∀`)
忘れなければそのうちやるw

参考:
GoogleのAIとNTTのAIを融合したら最強の業務カイゼンツールが爆誕した
ServiceAccountCredentialsのインポートエラー

うにのトゲは刺さると痛い(´・ω・`)-33

結局、力尽きた…_| ̄|○

TowerDefenceTutorialのTowerフォルダ以下のコードまでは目を通したが、力尽きたというか、

飽きた(・∀・)
ということで挫折(ノ∀`)

読み進める為に参考にしたエントリは以下の通り。理解したと思ってもすぐ忘れてしまうので、またいつか読む時の為に。

参考:
デリゲートとは【C#】
【Unity】UnityEventの用法と用量
数学系の処理を扱うMathfの全変数と全関数【Unity】
[Unity][Unity3d] Unity の C# で限りなく小さい float 値を使いたい時には float.Epsilon を使ってはダメ
Time.fixedDeltaTimeとTime.deltaTimeについて
【Unity】ISerializationCallbackReceiverを使ってみたんだ
数学系の処理を扱うMathfの全変数と全関数【Unity】
インデクサー
Java プログラマのための C# 入門 (#4 クラス定義の応用的なことと演算子のオーバーロード)


何故かMole's Match-upはリファクタリングを開始している。
中学生漢字データを作成しないといけないのに(ノ∀`)

何はともあれ、遊んでないで早く仕事を探さないといけない…(ヽ'ω`)