Scribble at 2022-07-16 15:57:27 Last modified: 2022-07-16 16:39:09

途中で学ぶのを止めていた Go については、再び元に戻って勉強しなおすこととした。最大の懸案だった、RoundToEven() という関数の挙動について、さらに調べたら事情が分かったからだ。つまり、この関数は「入力した数に最も近い『偶数』」を返す関数などではなかった。偶数に丸める関数ではないのだ。いや、正確に言えば結果を返す途中で偶数に丸めているのだ。どういうことかというと、

fmt.Println( math.RoundToEven( 2.7 ) )

僕は「最も近い偶数」に丸めてくれる関数だと思っていたのだが、RoundToEven() の基本的な挙動は、実は「最も近い整数」に丸めてくれるだけの関数と同じだ。しかし、RoundToEven() が独特であるのは、

fmt.Println( math.RoundToEven( 2.5 ) )

のように、2と3のあいだでどちらに丸めたらいいのかという基準が必要な数が与えられたときに、「偶数の側に丸めてから返す」という基準を採用していることにある。よって、偶数に丸めているのは途中の処理においてであり、最後に返す値は偶数でも奇数でもありうるわけである。よって、

fmt.Println( math.RoundToEven( 1.4 ) ) // 1 を返す

fmt.Println( math.RoundToEven( 1.5 ) ) // 2 を返す(1と2なら偶数の2を選ぶ)

fmt.Println( math.RoundToEven( 2.4 ) ) // 2 を返す

fmt.Println( math.RoundToEven( 2.5 ) ) // 2 を返す(2と3なら偶数の2を選ぶ)

fmt.Println( math.RoundToEven( 2.6 ) ) // 3 を返す

という挙動になる。これはこれで仕組みが分かったのでクリアになったのだが、でもこんな基準で処理する関数が必要となるシーンを想像するのは難しい。こんな、僕にはおよそ頻繁に生じるとは思えない特別な処理を要するルーチンが必要なシステムがあるなら、その場合に応じて特別なユーザ・メソッドを定義して使えばいいだけではないのかと思う。こんなものを、ビルトイン関数ではないにしても、標準的なパッケージに組み込んでいる意図がよくわからない。それとも Google では、こういう奇妙な基準で処理する何か特別な事情でもあるんだろうか。僕はプログラミングの仕事をしてお給料をもらうようになってから20年以上が経つけれど、こんな条件で入力値を処理したことは一度もないし、これからどういう案件が来ても、たぶんこの関数がキーになるようなルーチンを設計することは死ぬまでないと思う。よって、Go の勉強はするけれど、この関数については(これだけ調べたり記事を書いた以上は忘れようもないが)プロのエンジニアとしては、この世に存在しないものとして無視すると思う。同じ挙動のルーチンが必要になっても、われわれはこの程度の仕様(言わば foobar の応用みたいなものだ)のルーチンなど数分で書ける。DRY? それは無能のためのセリフだ。

  1. もっと新しいノート <<
  2. >> もっと古いノート

冒頭に戻る


※ 以下の SNS 共有ボタンは JavaScript を使っておらず、ボタンを押すまでは SNS サイトと全く通信しません。

Twitter Facebook