Code Style (日本語)

はじめに

"コードスタイルの強制とは時間が毎秒無駄になります"。 -- ある時、誰かによれば。

状態: 誤り

オープンソースの世界 (クローズドソースの世界に関しても) 本当にうつくしいソースに出会うとき、ソフトウェアが素晴らしい品質がであることをいつも確信しています。もちろん、時と場合によりますので、これは実のところ正確ではないかもしれませんし、スタイルは嘘をつくこともありますが、人々にとって高品質にであることが重要であると思います。これに反して、酷いコードに出会ってしまったときは (本当に素晴らしい品質があるかもしれませんが)、ある選択肢を試して発見することに関しては魅力的です。 心理的に、コードスタイルの実施は技術面において時間の無駄かもしれません。また、作業時 (それを完了したとき)に LÖVE を基準として使用するつもりならば、コードに 10 秒間の探索をするだろうという僅かな見込みがあります。たとえ適切にコードを評価するための十分な技能があるとしても、良い (または悪い) スタイルに免疫がないものと思われます。

したがって、このような酷い怠け者であるため、コードの一部をよりうつくしくするためにあちこち (またはどこであろうと)、コードのリファクタリングを行います。とにかく、あらゆることが潜在的に酷いので、大多数が好むであろうコードスタイルを決定できたと思います。これらすべてを全員が認めることはないでしょう……が。大多数の皆さんが決定を認めていただけることを望みます。

Namespaces

Namespace 本文の字下げはしないでください。

推奨:

namespace love
{
namespace graphics
{

class Foo
{
public:
  /* ... */
};

} // graphics
} // love

禁止:

  
namespace love
{
  namespace graphics
  {

      class Foo
      {
      public:
          /* ... */
      };

  } // graphics
} // love

クラス宣言

先頭一文字目の英字は大文字にしてください。

推奨:

class Foo
{
};

禁止:

class foo
{
};

class FOO
{
};

ブロックの可視性は徐々に狭くなる順にしてください。

見てわかる通り最初に "API" があることは意味のあることです。これは、通常において読者がとにかく最初に知りたいことであるからです。

推奨:

class Foo
{
public:
protected:
private:
};

禁止:

class Foo
{
private:
protected:
public:
};

多重継承では、各クラスは別々の行に記述してください。

各行はコロンまたはカンマで始めてください。私の経験において、これが diff コマンドと ifdeffery に関して最も柔軟性があるスタイルです。

推奨:

class Foo : public Bar
{
};

class Foo
  : public Bar
  , public Foz
{
};

禁止:

class Foo : public Bar, public Foz
{
};

初期化指定子リスト

継承リストと同様に、初期化指定子は別々の行に記述してください。

推奨:

Foo::Foo()
  : bar(0)
  , foo(1)
{
}

禁止:

Foo::Foo() : bar(0) , foo(1)
{
}

関数・メソッド

関数およびメソッドにはキャメルケースを使用してください。

推奨:

int doomFist(int where);

禁止:

int DoomFist(int where);
int doom_fist(int where);

括弧は間にスペースを挟まず名前の直後に記述してください。

推奨:

int doomFist(int where);

禁止:

int doomFist (int where);

開括弧の直後および閉括弧の直前には余計なスペースを記述しないでください。

推奨:

int doomFist(int where);

禁止:

int doomFist( int where );

クラス宣言においてゲッターとセッターは一行記法 (One-liner) によりインライン化できます (一行以上ならばインライン化しないでください)。

推奨:

class Foo
{
public:
  void setBar(int bar) { this->bar = bar; }
  int getBar() const { return bar; }
private:
  int bar;
};

非推奨:

class Foo
{
public:
  void setBar(int bar);
  int getBar() const;
private:
  int bar;
};

void Foo::setBar(int bar)
{
  this->bar = bar;
}

int Foo::getBar() const
{
  return bar;
}

制御ブロック

制御ブロックはキーワードと式括弧の間を空けて記述してください。これは関数呼び出しからの制御文を視覚的に区別しやすくするためのです。

推奨:

if (foo)
  /* ... */;

禁止:

if(foo)
  /* ... */;

可能であれば、通常は括弧を省略してください (縦方向の空間を残しておくためです)。

推奨:

if (foo)
  bar();

禁止:

if (foo)
{
  bar();
}

推奨:

if (foo)
  bar();
else
{
  foz();
  baz();
}

禁止:

if (foo)
{
  bar();
}
else
{
  foz();
  baz();
}

括弧は次行に記述してください。

推奨:

if (foo)
{
  bar1();
  bar2();
}

禁止:

if (foo) {
  bar1();
  bar2();
}

ポインタの類似性

ポインターと参照において、アスタリスクおよびアンパサンドは変数名側に記述してください。

これは間接参照 (*foo) との整合性を保つためであり、ほとんどの LÖVE 開発者の間では好まれている記法です。

推奨:

int *foo;
int &bar;

禁止:

int* foo;
int& bar;

int * foo;
int & bar;

推奨:

int *get_int_ptr();
int &get_int_ref();

禁止:

int* get_int_ptr();
int& get_int_ref();

int * get_int_ptr();
int & get_int_ref();

スペース vs タブ

筆者個人としてはタブのほうが好みですが、それは世界中で筆者だけであることがわかっています。結局はスペースを選択するでしょう。よって、その場合は1つのレベルに対して4文字のスペースの使用を提案します。

追記: 筆者の考えは間違っておりました。これまでのところ関心を持った方々はタブを好まれています。この場合、ハッカー風 (訳注: l33t - 本来の意味です) の本格的かつ正確で先進的なインデントのガイドラインを指定させていただきます。

タブとスペースの併用 (*モノクルポップス*)

通常はインデント (字下げ) ではタブを使用してください。

すなわち、有効範囲 (スコープ) を示すためです。

推奨:

if (foo)
{
<tab>bar();
}

禁止:

if (foo)
{
<space><space><space><space>bar();
}

整列にはスペースを使用してください。

本当に整列を必要とするならば、考慮すべき重要なことは、あなたが使用しているビューアソフトとは異なる1タブ当たりの幅が使用されている場合には、整列を破綻しないようにすることです。そのため、この用例では、内容を整列しています:

if (foo)
{
    int a_var      = 1;
    int anoter_var = 2;
    int moar       = 3;
    int doom       = 4;
}

推奨:

if (foo)
{
<tab>int a_var<space * 6>= 1;
<tab>int anoter_var<space>= 2;
<tab>int moar<space * 7>= 3;
<tab>int doom<space * 7>= 4;
}

禁止:

if (foo)
{
<tab>int a_var<tab * 2>= 1;
<tab>int anoter_var<tab>= 2;
<tab>int moar<tab * 2>= 3;
<tab>int doom<tab * 2>= 4;
}

しかしながら、現時点で最長のものに長いものを追加すると、 diff コマンドを使用したときに不必要な情報を生成してしまうため整列は控え目に使用してください。それでも実際には最良の選択肢です:

末尾のスペース

末尾のスペースを削除してください。

改行文字の前にタブおよびスペースがあるとコミット時にソースコードの不要情報が増えてしまいます。

推奨:

<tab>foo();

<tab>bar();

禁止:

<tab>foo();
<tab>
<tab>bar();

ドキュメンテーションブロック

アスタリスクは垂直方向に整列してください。

推奨:

/**
 * 手短な説明。
 *
 * @param foo bar には foo が入ります。
 * @param bar bar は foo の反対です。
 */
int foz(int foo, int& bar);

禁止:

/**
* 手短な説明。
*
* @param foo bar には foo が入ります。
* @param bar bar は foo の反対です。
*/
int foz(int foo, int& bar);


これに認める場合は、さらにタブを使用することにも認めてください。タブとスペースの併用も認めます (非常に明確なことです)。 1ブロックのインデントで記述を行う関数の宣言では、このように入力します:

 <tab>/**
 <tab><space>* 手短な説明。
 <tab><space>*
 <tab><space>* 長めの説明。
 <tab><space>*/

#includes

システムインクルードではないならば、ダブルクォートを使用してください。

推奨:

#include "common/config.h"

禁止:

#include <common/config.h>

キャスト

C スタイルのキャストを使用してください。

C スタイルのキャストを使用しているときに何のために何をしているのかを忘れないようにしてください。

推奨:

Foo *foo = (Foo *) bar;

禁止:

Foo *foo = (Foo*)bar;
Foo *foo = (Foo*) bar;
Foo *foo = (Foo *)bar;

null 文

NULL または 0 よりも nullptr にしてください。

推奨:

foo = nullptr;
bar = nullptr;

禁止:

foo = NULL;
bar = 0;


そのほかの言語