2022年5月12日木曜日

【Android USB oscilloscope】(30) Kotlinで大域変数を使う Companion object

余っているAndroidスマホをオシロにしよう!

USB BULK転送で転送レートがどこまで出るのかを試そうとしています.
転送レートを制限する要因は、STM32 host、USB2.0、スマホ があるわけですが、USB2.0の理論限界480Mbpsまでは絶対にいけません.経験的に16MByte/Secが出たらネ申ってとこ.10MByte/Secでも褒めてあげたいレベル.
STM32 firmwareは内部でDMA使ってると思うのでtune upは難なく完了すると予想しますが、スマホはどうなっちゃうんですかね? バックグランド処理が邪魔するのでpacket落ちしない程度までレートを下げるとかなり遅くなってしまうというオチが予想され背筋が寒いです.
(現在800kByte/Secというショボさで泣く....)

レートはさておき、今回の投稿はKotlinの大域変数についてです.

かつてこんな投稿をしたことがあります.Kotlinで大域変数を使いたいのだけれどどうやったらいいのかな?という疑問でした.
この投稿の時点での知見では大域変数的な運用するのはやればできる.大域変数ばかり集めたobjectを1つだけ作り、そいつを他classのobjectに引数で渡してやればいい.実際にそれで大域変数的運用をやっています.

なのですが、、、そんなめんどくさいことをしなくてもモロに大域変数みたく使う仕組みがKotlinに在ると知りました.それが Companion object です.

実例を挙げます.こんなクラスを作ります.classの中にcompanion object{...}を書くだけです.中身には大域運用したい変数を書きます.
class USBparams {
    companion object {
        var model : String? = ""
        var manufacturer : String? = ""
        var serial : String? = ""
        lateinit var timeStart : LocalTime
        lateinit var timeNow : LocalTime
    }
}
そして、これをどうやって呼び出すのかがキモなわけですが、こんな特徴があります.こんな魔法のような仕様があっていいんか(笑).
・companion objectを複数個生成しても、参照先は1つのobjectに絞られる ←魔法
・それどころかobject生成しなくていい  ←なんたる掟破り
・companion objectのメンバ変数を呼び出すには、他のclassからでもいきなり、USBparams.model=”TS-1” のように呼び出せる  ←なんたるアバウト

Kotlinには大域変数は無いと云われますが、これなら事実上大域変数みたいなもんじゃないかな? 抜け道ですかぁ?

Kotlinはマイナー仕様が後から湧いて出てくるので困るじゃん.

29へ    31へ

かしこ

15 件のコメント:

  1. companion object についてのコードを載せた者です。不思議だ。全然呼ばれてないのに、しばらくぶりにこのサイトに来たら、ちょうど、この記事が書かれたあと。

    https://craftofcoding.wordpress.com/2015/12/07/memory-in-c-the-stack-the-heap-and-static/

    – static: global variable storage, permanent for the entire run of the program.
    – stack: local variable storage (automatic, continuous memory).
    – heap: dynamic storage (large pool of memory, not allocated in contiguous order).

    返信削除
    返信
    1. Synchronicity というやつが起きましたね.ナイスー

      削除
  2. companion object については、私にはこの解説一番わかりやすかったです。

    https://qiita.com/tkhs0604/items/261e94a42b7097dfd204
    Kotlinのcompanion objectとは
    ・companion objectはクラス内に作成されるSingletonのことです。
    ※この一言で、私にはよくわかりました。要するに、c#の static と同じですね。
    c# も、class内で、 static hoge; と、宣言すれば、プログラムのどこからでも、
    クラス名.hoge で、参照できるようになります。classのインスタンス化も不要です。
    (逆に、classのインスタンスから呼ぶと、叱られます。)

    >こんな魔法のような仕様
    c# の static も、「まったく同じ」性質を持ちます。この性質が「Singleton」と呼ばれる所以です。
    要するに、「Singleton」とは、classで無理やり作った「グローバル変数」のようなものです。
    ※「Singleton」については、
    Singleton パターン
    https://ja.wikipedia.org/wiki/Singleton_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3
    も、参考になります。

    ※オブジェクト指向って、「グローバル変数禁止」とか言いながら、こういう
    「抜け道」みたいなのがよくあります。つか、「排他制御用の変数」とか、絶対こういうのが
    「必要」
    ですからねぇ・・・(インスタンス変数では、絶対に無理。)

    返信削除
    返信
    1. >「グローバル変数禁止」とか言いながら、こういう「抜け道」みたいなのがよくあります.「排他制御用の変数」とか、絶対こういうのが「必要」

      なるほどいわれてみればそうですね.

      実はわたしも同じページでcompanionを理解しました.

      しかし今だにsingletonの意味はわかんないです(言葉は聞いてたけど).singletonが大域変数運用に使えるのは今回の事例でわかったけれど、なんでもかんでも単一objectで一気通貫するのってよくわかんないんですよね.足し算もできねぇじゃんみたいな.ぎゃふん

      削除
    2. そういえば、C#、VB、VCなど、MSの言語って一度も使ったことがないや.ぎゃふん

      削除
    3. >singletonの意味
      「singleton」とは、英語で「一人っ子」の意味らしいので、それから考えると、
      ・兄弟のいないインスタンス
      と、考えることができます。

      例えば、class A があったとして、
      a = new A()
      b = new A()
      とやると、俗に、
      a, b は、「兄弟インスタンス」(英語的には、sibling になると思うので、日本語の「兄弟」とはちょっとニュアンスが違いますが、要は「同じ親を持つもの」みたいな意味です。)と呼ばれます。
      singleton とは、
      ・b = new A() ができない、あるいは、a=b になってしまう
      ・そもそも、a = new A() ができない、A自体が、プロパティやメソッドを持てる
      のようなものです。(言語によって、扱いが違う。)

      ※これは、いわゆる「グローバル変数」とは、概念が違うので、例えば、
      private 属性をつけて、「class 内部でしか参照できない singleton」などを
      作ることができます。

      ※あと、オブジェクト指向言語は、基本的に、
      「class で定義したものを、new でインスタンス化(実体化)」しなければならない(明示的、暗示的 問わず)ので、
      このような「めんどくさい」ことになってるんだと思います。

      削除
    4. >C#、VB、VCなど、MSの言語って一度も使ったことがない
      まぁ、無理して使うこともないです。クセが強いし。
      ※そんな言語より、pythonでもやってたほうがマシなような気がする。
      (pythonも、別の意味でクセが強いみたいですが。実は私もよく知りません。)
      Javascript (nodejs とか)は、一通りやっておくといいかも知れません。

      削除
    5. >基本的に「class で定義したものをnew でインスタンス化(実体化)」しなければならない

      verilogはhardware記述するものなので、逃げ道なくインスタンスしなくちゃ動きません.(インスタンスせなFPGAの中にlogic回路が生成されない)
      なのでobject志向もそうだよね、逃げ道ないよね、と思ってたのに逃げ道があってよかったです.というかぎゃふんー

      削除
    6. MSの言語に手出ししないのは基本有料だからかなぁ.
      あとupdateで仕様が大きく変わりそうな気もするかなぁ.

      pythonってもっと高速動作だとやる気出るんですけね.信号処理やらせるとのろくてぎゃふんー

      削除
  3. まったくの余談ですが、
    「シングルトン」
    という、占星術用語があって、意味的には、ホロスコープを見たときに
    「ポツンと、一つだけ、離れたところにいる星」
    のことを表します。

    ※ちょっと検索したら出てきた解説
    https://astrobeauty.jp/blog-9/
    【ホロスコープ】シングルトン~ポツンとある天体

    ※占星術では、ホロスコープ上の、星の位置や相対角度に意味があって、
    特にこの「シングルトン」というのは、強力な意味を持ってたりします。
    どうも、「シングルトン」と聞くと、こちらばかりを思い描いてしまいます。

    返信削除
    返信
    1. 奥さんが占星術に詳しいのですがわたしはさっぱり.
      なおいて座のO型です.

      占星術なのか知らんですがわたしは霊合星人らしい...

      削除
    2. >霊合星人
      これは、端的に言うと、
      「一筋縄ではいかない、相反する運命にある」人らしいです。

      ここ
      https://www.fujingaho.jp/culture/interview-celebrity/a30921719/hosokikaori-200221/
      霊合星人とは? 運気が倍増したり相殺されたり、ひと筋縄でいかない星
      に、解説がありました。
      (ちなみに、私もそうらしい。「天王星人の霊合星人」と出ました。)

      削除
    3. わたしは木星の霊合星でしたかな.存在比率はそんなに多くないらしいですがね.いるとこにはいるというw

      >運気が倍増したり相殺されたり

      なんかロクでもない.カチッと制御したいもんです.

      削除
  4. イメージで言うと、pythonは頭のいい学者が作った言語、javaは大学院生が作った言語、kotolinは高専生が作った言語。

    返信削除
    返信
    1. あぁわかる、その気持ち.

      ソフト素人のひら的には、
      python 大棚ざらえでscript言語の大棚ざらえの究極版
      java  ぐぁーめんどくせー、ポリコレ、マナー大切
      kotlin  立ち食い蕎麦

      削除