動的に型付けされた言語で列挙型が必要なのはなぜですか?


32

ここでいくつかのコードを読んでいて、enumがhtmlタグの名前を保存するために使用されているのを見ました。なぜこれを行う必要があるのでしょうか?この戦略を使用するとどのようなメリットがありますか?

コンパイルされた言語または静的に型付けされた言語で列挙型がどのように役立つかは知っていますが、動的に型付けされた言語で列挙型を見ると、上記のコード例のように興味があります。それで、質問は基本的に、動的に型付けされた言語で列挙型が必要なのか、それともまったく必要なのか、ということです。


38
この質問は基本的に「なぜ型が必要なのか」です。
user11153

1
リポジトリを検索して、その呼び出し方法を確認しましたか?そうすれば、受け取った答えをよりよく理解できるでしょう。
ラバーダック

次のものがある場合:enum People { YOU, NPC, FOO, BAR }および(People)intを必要とする関数は、番号を使用する代わりに、何でもプラグインできます。
エヴァン・カースレイク

3
この特定の「enum」の目的について、または一般的な列挙型の目的について、どの言語でも尋ねていますか?...私は、元を取るだろうが、現在のすべての答えは、後者を考えているようだ
メリトン-ストライキに

回答:


56

利点は、誤って「ADRESS」または「FEILDSET」と入力したかどうかをコンパイラが通知できることと、実行時に無意味な方法で動作するのではなく、すぐに修正できることです。

この利点は、静的に型付けされた言語では動的よりもはるかに便利ですが、実行時エラーであっても、データではなくcaseステートメントに問題があることを示すメッセージが表示されるため便利です。


4
@amon:可能ですが、enumsは衝突を起こさないようにするための便利なメカニズムを提供します。
whatsisname

75
私が使用列定数の代わりに、列挙型、貧しいエディタのフォント、偶然というフィールドに誰かの明るいアイデアによって引き起こされるバグを追いかけ月過ごした後の作業に使用場所"PROF1LE_"
ゴートロボット

8
@amon Goはまさにこれを行います。ただし、enumの良い点の1つは、コンパイラーがswitchステートメントにすべての可能なenum値のケースがあることを確認できることです。
weberc2

15
このコードは80年代に書かれました。これに気付かないかもしれませんが、これは、一部の開発者が1つのキーを持っていなかった物理的なタイプライターで開発することを学んだ時代でした。実際に問題の文字列は「Profi1e」であることに気づきましたが... 25年ぶりなので、私の記憶は明らかに完璧ではありません。
ロボット

4
@DarrelHoffman:あなたが驚いたことに驚いています。Perlでは、$1という意味で頻繁に入力します$i。(確かに、私が入力したことがないf1leのではなくfile- $1間違いが事実によってプライミングされる$1Perlで非常に一般的である- 。それでも、すべての種類の間違いが共通しているかもしれないDEVはとパスワードを持っていたprof1leことで、それによって、ミスタイプにそれらをプライミングprofile非パスワードコンテキストで。)
ruakh

22

列挙型は、適切な値/エンティティの固定セットがある場合に役立ちます。これらは自己文書化されており、コンパイラが実行時に残されることを検証できます。意味のある値のセットが不明であるか、厳密に制限されていない場合は、決して使用しないでください。

より便利な例は、HTTP応答コードのようなものです。番号を取り、エラーの名前や説明を提供するメソッドを持つ代わりに、意味のある名前、コード、説明などを含む列挙のセットを、値が何であるかについて信頼できる1つのクリーンパッケージに入れることができます。許可され、処理する必要があります。


1
「自己文書化」は最も重要な部分です。そのソフトウェアを保守している人が何が起こっているかを理解できるように、私はむしろ、status === GEOLOCATION_ACQUIREDよりもむしろチェックしたいstatus === 3です。あなたが言ったように、無効な値も防ぎます。
ニコラスブーリアン

11

EnumはOOPとは関係がなく、JavaScriptにはenumがありません。代わりに、値の固定セットの選択肢がある場合は常に列挙型が使用されます。たとえば、ブール値はtrueとfalseの間の選択で、として実装できますenum Bool { False, True }。GUIライブラリーには、アライメントの列挙型がある場合がありますenum HAlignment { LEFT = -1, CENTER = 0, RIGHT = 1 }

通常、enumの実装方法は関係ありません。重要な部分は、可能な値がそれぞれ異なることです。Javaなどの一部の言語は任意のオブジェクトをサポートしていますが、多くの言語は列挙型に整数を使用しています。

これまでは、定数などを使用することもできましたconst int LEFT = -1, CENTER = 0, RIGHT = 1。ただし、コンパイラーは列挙値が一緒に属することを知っています。したがって、列挙値を切り替えるswitch(value) {case LEFT: ...; case RIGHT: ...;}と、コンパイラは、CENTERケースを忘れたことを警告できます。これにより、大幅に時間を節約できます。列挙型またはswitch-caseコンストラクトのない言語では、Visitor Patternを使用してこれをシミュレートできますが、静的型付けが存在する場合に役立ちます。

もう1つの利点は、列挙型を別の型として扱うことができることです。たとえば、メソッドがHAlignment整数ではなくパラメータを取ることを宣言できます。3つの可能なHAlignment値の1つ以外を指定すると、コードはコンパイルに失敗します。ただし、Cの列挙型はカプセル化されていないため、列挙型定数は整数と同じ意味で使用できます。他の言語はここでより厳密です。

JavaScriptでは、これらの利点はありません。与えられた例は、enumとして扱われるオブジェクトを宣言しています。これにはプログラマーにとっていくつかの利点があります。例えば、文書化を容易にし、すべての「定数」を単一のオブジェクトにグループ化します。ただし、そのようなオブジェクトが列挙型になっているのは単なる規則です。

ここでのポイントは、HTMLには有限の既知のタグセットしかありません。HTML5仕様を見て、それらの要素名を列挙型としてコードに入れることができます。そのため<blink>、プログラムにタグを忍び込ませることがより困難になります。この知識を1つの場所にエンコードして、コードに特別な文字列リテラル(または、さらに悪いことに、マジックナンバー)を散らかす方がよいでしょう。


その場合<blink>、javascriptのメソッドに渡しても何も私を止めることはできませんか?しかし、javaこんにちはで休憩:)
CodeYogi

@CodeYogiはい、JSには静的型システムがなく、特に列挙型の概念がないためです。ただし、メソッドのパラメーターを「TagNameを取得する」として文書化することができます。これにより、プログラマーfoo(TagName.STRONG)はそれを呼び出すと少し良くなります。フィールドが存在しない場合にJSが文句を言うとさらに良くなりますが、ここではundefined試してみる場合にのみ取得しTagName.BLINKます。JSではあまり価値がありませんが、それは始まりです。
アモン

うーん、上で述べたコードリンクはクロージャーコンパイラを使用しているので、そこで意味があります。
-CodeYogi

Clojureは関数型言語であるため、OOPが質問にどのように関連するのかわかりませんが、それ以外に、通常は整数のセット(OOではない)とOOである 'Typesafe enum'パターンを区別することが重要ですJavaがサポートするもの。
ジミージェームズ

私はJSについて、いないのClO話して@JimmyJames jは(もある程度OOPをサポートし、Javaプラットフォーム上で実行されている、)URE。質問にはoopというタグが付けられていたため、最初に言及したのはそのためです。タイプセーフな列挙型がOOPにどのように接続されているのか、実際にはわかりません。これは単なるタイプシステム機能です(多くの非OOP言語にはタイプシステムがあります
:

3

あなたの言語がコンパイルを必要としない場合でも、おそらくある種のIDEまたは開発ツールを使用するでしょう。それは、単なる文字列よりもenumのようなものに対してより良いサポートを提供できます。

たとえば、javascriptでオブジェクトリテラルのような列挙型を使用すると、誤った値を誤って使用した場合、エディターでコード補完が行われ、JSHintやJSLintなどのコードチェッカーで警告が表示されます。


私は、他の多くの反応がこの点を逃したか、打ち負かしたと思います。動的言語で 'emum'を使用してもコンパイラには何の効果もありませんが、特定のIDE、ドキュメントツールを実際に役立てることができ、コードを理解しようとする人間を忘れないでください。
ロバート

2

このような列挙型のポイントは、許可されたタグのセット/バンドルをJs Api(goog)に提供することです。どれ?W3C HTML 4.01で定義されているもの(列挙型のドキュメントをご覧ください)。設定の境界です。

これが本当の目標かもしれないし、そうでないかもしれないが、そのような目的のためにはうまくいくだろう。

Javascriptがどのように機能するかを知っている場合、コードが実行しているのは、文字列でインデックス付けされた配列の定義です:-) どの値は文字列ですが、属性、関数などを備えた他のコンポーネントでもかまいません。想像力を自由に働かせれば、どこでもメリットが得られます。

Javascriptは別として、ステートマシンのモデリングと管理には列挙型を多く使用します

START> IN_PROGRESS> CONFIRMED> FINISHED> ...

Java スイッチでは列挙型が許可されるため、状態を状態マシンに検証し、列挙型全体をループし、複雑な列挙型を実行して優先順位を定義することは非常に簡単です...

また、これらを使用して、型指定された修正不可能な定数を定義します。

  • はい・いいえ

また、複雑な列挙(安全な変換/パーサーを実行できます)

  • はい(1、true)、いいえ(0、false)

列挙型は多くの場合私のモデルレイヤー(コア)に属しているため、その機能はシステム全体でアクセス可能であるため、機能モデルになり、結合度は低くなります。

enumsが(とりわけ)与えるものは、境界類型化です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.