KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

Go言語設計哲学と「三項演算子」のあいだ

Go言語は2009年にリリースされて以降、「シンプルで明快」な設計哲学を貫いてきたことで知られています。C言語やJavaといった、多機能で柔軟性の高い言語から移行してくると、Goの最小主義的な設計には「そこ切り捨てちゃう?」という驚きがありますよね。
そんなGoでは、「あえて存在しない」ものがいくつかあります。そのうちの一つが「三項演算子」ですよね。三項演算子が大好きな私です。切ない別れです。

なぜGoは三項演算子を採用しなかったのか?

C言語などでお馴染みの三項演算子 condition ? expr1 : expr2 は、「ある条件が真ならexpr1、偽ならexpr2」という値を返す簡潔な記法です。便利に見えますが、Go言語はこれを採用しませんでした。その背景には以下のような考えがあります。

  • 可読性と明快さの優先
    三項演算子は慣れてしまえば手短ですが、初見の人には少し理解しにくい場合もあります。Goはコードを読む人に優しい言語を目指すため、if-else ブロックによる明示的な条件分岐に統一した・・・ということのようですが、実際には「三項演算子が読みやすいか読みにくいか論争」というのがこの業界にはありまして、三項演算子をシンタックスごと除去することでその不毛な議論を終わらせたんじゃないかと思います。

  • 構文の単純化
    言語仕様を極力シンプルに保つことはGoの重要な方針です。三項演算子を導入すれば、それ専用のパーサールールや仕様決めが必要になります。Goはあえて機能を絞り込み、言語が持つ心的負荷を低減しています。

これらの理由から、Goの公式言語仕様や標準ライブラリは、三項演算子を設けず、ifによる分岐でシンプルさを維持してきました。

しかし、サードパーティに「Ternary」な関数は存在する

ただし、Goエコシステムはオープンであり、多数のサードパーティライブラリが存在します。その中には「lo」のようなユーティリティライブラリがあります。loは標準ライブラリにはない便利関数を多数提供しており、その中には、条件に応じて戻り値を切り替える「三項演算子風」の関数 lo.Ternary が存在します。

これを見て「Goの設計哲学と矛盾しているのでは?」と思う方もいるでしょう。確かに「公式」な観点から言えば、Goはなるべく冗長な糖衣構文を排したいはずです。しかし、lo はあくまでサードパーティ製のライブラリです。Go言語本体や標準ライブラリでは守られるべき哲学がありますが、それ以外は基本的に自由です。

設計哲学とエコシステムの関係

Goは「標準ライブラリ」と「言語仕様」に対して、シンプルであること、読みやすいこと、最低限であることを徹底しています。その一方で、Goは開放的なエコシステムを持ち、サードパーティは独自の価値観に基づいてさまざまな拡張を提供できます。これは、Goが「こうあるべき」という強制ではなく、「こうあることが望ましい」というベースラインを示し、そこから先は利用者に委ねる、というスタンスを取っていることの表れです。

「Goの設計哲学を重視するなら、if を使えばいい」のですし、「もう少し便利な記法が欲しい」というニーズがあるならば、サードパーティのツールを使っても構いません。最終的には、プロジェクトのコーディング規約やチームの好みに従って選択するのがよいでしょう。

まとめ

  • Go言語は三項演算子を公式に提供せず、シンプルなif-else構造を好みます。
  • これはGo言語の設計哲学に根ざしたもので、明快さ・可読性・構文の単純化が目的です。
  • 一方、サードパーティのユーティリティライブラリ(loなど)は独自に「Ternary」的な関数を提供することもあります。
  • これらはGo公式哲学と必ずしも調和していないようにも見えますが、言語仕様や標準ライブラリを超えたエコシステムでは、開発者が必要に応じて利用するオプションに過ぎません。
  • Goの思想を徹底したければ標準的なif-elseを使えばよく、別途便利さを求めるならlo.Ternaryを利用する自由もあります。

Goはあくまで「基準」を提示しているに過ぎず、その上でコミュニティが何を選択するかは自由。ってことになります。「ふさわしくない」と感じるなら使わなければよいだけです。ただ、その「基準」自体は知ったうえで選定をするべきでしょうね。
まあ、lo.Ternary が三項演算子の代わりになるかちゅーと、読みにくいので、代わりにはなってない気はしていますが・・・。