Mid$とMidって何が違うのさ?

はじめに

今回は特に何かの目的を達成するというものではなく、ちょっと気になったことの確認程度です。

ふとその辺のVBのコードを見ていたらMidMid$の2種類が使われているのに気付きまして、何か違いがあるのかと疑問に思ったわけですよ。

Let's IL

まぁ、検証としましても二つ用意して逆アセンブルしてILを確認して終了です。

Dim a = Mid("Hello World", 2, 4)
Dim b = Mid$("Hello World", 2, 4)

そしてこちらに逆アセンブリ済みのものを用意しました。

.maxstack  3
.locals init ([0] string a,
              [1] string b)
IL_0000:  nop
IL_0001:  ldstr      "Hello World"
IL_0006:  ldc.i4.2
IL_0007:  ldc.i4.4
IL_0008:  call       string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
                                                                                      int32,
                                                                                      int32)
IL_000d:  stloc.0
IL_000e:  ldstr      "Hello World"
IL_0013:  ldc.i4.2
IL_0014:  ldc.i4.4
IL_0015:  call       string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
                                                                                      int32,
                                                                                      int32)
IL_001a:  stloc.1
IL_001b:  nop
IL_001c:  ret

全く同じ

逆に安心しました。これで呼び出される命令やメソッドが異なっていたりしたらまた一つバッドノウハウを発掘してしまうところでした。

ヤフーでググった所レガシーVBVBAではMid$が文字列を返してMidがバリアント型を返すのでMid$の方が早いのどうのこうのというお話があるそうです。 500万回繰り返して2秒ほど高速だのどうのってわざわざ検証ご苦労様です。*1

速度的な話で余談ですが、VBString.SubstringMidではどちらが速いのかという話ですが、Midも内部でString.Substringを使用しているので理論上はメソッドの呼び出しが少ないString.Substringの方が高速ですが、正直マジで微々たる差なのでアホみたいにループ内で呼び出さない限りほとんど差はないはずです。 結論といたしましてはVBの主戦場である生産性アプリケーション開発において数回文字列操作を行う場合については別にどっちを使おうが大した差はないのでお好きな方をどうぞ。

さらにさらに余談ですが、あの$には意味があるみたいです。

型文字 (Visual Basic) | Microsoft Docs

記号で変数やメソッドの返り値の方が指定できるみたいです。 ですが正直あれで型を指定されてもクッソ分かりずらいだけなので、まぁ、その、使わないで欲しいです。

Sub Main()
    ' 等価な呼び出し
    Dim a = Hoge$("Hello World")
    Dim b = Hoge("Hello World")

    ' 明示的に指定された返り値の型が型文字と同じならこのように呼び出すこともできる
    Dim c = Hoge2%("Hello World")

    Dim d$ ' 変数はString型
    d = "Hello World"
End Sub

Function Hoge$(a As String) ' String型を返すメソッド
    Console.WriteLine(a)
    Return a
End Function

Function Hoge2(a As String) As Integer
    Console.WriteLine(a)
    Return 1
End Function

おそらくレガシーVBのバリアント型絡みで残されてるのでしょうけど、型文字に触れているサイトはほとんどありませんでした。 お前ら他の言語勉強するつもりがないにしてもせめて自分が使ってる言語ぐらい興味持てよ。と思ったところで今日はここまで。

おわり

*1:そんなこと言ったら弊社ブログも誰も気にしない事をわざわざ逆アセンブリして検証して文章を書いてるのだから人のことは言えないのですが