第15章 列挙型
15.1 基本的な列挙型
PHP(PHP 8.1+)
<?php
// Pure Enum(値なし)
enum Status {
case Pending;
case Active;
case Inactive;
}
// 使用
$status = Status::Active;
// 比較
if ($status === Status::Active) {
echo "Active";
}
// 列挙子名の取得
echo $status->name; // "Active"
// すべての値
$allCases = Status::cases();
TypeScript
// 数値列挙型
enum Status {
Pending, // 0
Active, // 1
Inactive // 2
}
// 使用
const status: Status = Status.Active;
// 比較
if (status === Status.Active) {
console.log("Active");
}
// 逆引き
console.log(Status[1]); // "Active"
// const enum(コンパイル時にインライン化)
const enum Direction {
Up,
Down,
Left,
Right
}
VB.NET
' 基本的な列挙型
Enum Status
Pending
Active
Inactive
End Enum
' 使用
Dim status As Status = Status.Active
' 比較
If status = Status.Active Then
Console.WriteLine("Active")
End If
' 名前の取得
Console.WriteLine(status.ToString()) ' "Active"
' 数値の取得
Console.WriteLine(CInt(status)) ' 1
' すべての値
For Each s In [Enum].GetValues(GetType(Status))
Console.WriteLine(s)
Next
15.2 数値型/文字列型 Enum
PHP
<?php
// Backed Enum(値あり)- 整数
enum HttpStatus: int {
case OK = 200;
case NotFound = 404;
case InternalServerError = 500;
}
// 値の取得
echo HttpStatus::OK->value; // 200
// 値から列挙子を取得
$status = HttpStatus::from(404); // NotFound(見つからないとエラー)
$status = HttpStatus::tryFrom(999); // null
// Backed Enum - 文字列
enum Color: string {
case Red = 'red';
case Green = 'green';
case Blue = 'blue';
}
echo Color::Red->value; // "red"
TypeScript
// 数値列挙型(明示的な値)
enum HttpStatus {
OK = 200,
NotFound = 404,
InternalServerError = 500
}
console.log(HttpStatus.OK); // 200
console.log(HttpStatus[200]); // "OK"
// 文字列列挙型
enum Color {
Red = 'red',
Green = 'green',
Blue = 'blue'
}
console.log(Color.Red); // "red"
// 文字列enumは逆引き不可
// 異種混合(非推奨)
enum Mixed {
No = 0,
Yes = "YES"
}
VB.NET
' 基底型の指定
Enum HttpStatus As Integer
OK = 200
NotFound = 404
InternalServerError = 500
End Enum
Console.WriteLine(CInt(HttpStatus.OK)) ' 200
' 数値から列挙子を取得
Dim status = CType(404, HttpStatus) ' NotFound
' 文字列から変換
Dim parsed As HttpStatus
If [Enum].TryParse("NotFound", parsed) Then
Console.WriteLine(parsed) ' NotFound
End If
' VB.NET には文字列enumはない
' 代替:定数または拡張メソッド
Module ColorExtensions
<Extension()>
Public Function ToColorCode(color As Color) As String
Select Case color
Case Color.Red : Return "#FF0000"
Case Color.Green : Return "#00FF00"
Case Color.Blue : Return "#0000FF"
Case Else : Return ""
End Select
End Function
End Module
15.3 フラグ Enum
PHP
<?php
// PHP にはフラグenumの組み込みサポートはない
// ビット演算で実現
enum Permission: int {
case Read = 1;
case Write = 2;
case Execute = 4;
}
// 組み合わせ
$permissions = Permission::Read->value | Permission::Write->value;
// 確認
if ($permissions & Permission::Read->value) {
echo "Can read";
}
// ヘルパークラス
final class Permissions {
public const READ = 1;
public const WRITE = 2;
public const EXECUTE = 4;
public const ALL = self::READ | self::WRITE | self::EXECUTE;
}
TypeScript
// フラグ列挙型
enum Permission {
None = 0,
Read = 1 << 0, // 1
Write = 1 << 1, // 2
Execute = 1 << 2, // 4
All = Read | Write | Execute
}
// 組み合わせ
let permissions: Permission = Permission.Read | Permission.Write;
// 確認
if (permissions & Permission.Read) {
console.log("Can read");
}
// 追加
permissions |= Permission.Execute;
// 削除
permissions &= ~Permission.Write;
// 切り替え
permissions ^= Permission.Execute;
VB.NET
' Flags属性でフラグenumを宣言
<Flags>
Enum Permission
None = 0
Read = 1
Write = 2
Execute = 4
All = Read Or Write Or Execute
End Enum
' 組み合わせ
Dim permissions As Permission = Permission.Read Or Permission.Write
' 確認
If (permissions And Permission.Read) = Permission.Read Then
Console.WriteLine("Can read")
End If
' HasFlagメソッド(推奨)
If permissions.HasFlag(Permission.Read) Then
Console.WriteLine("Can read")
End If
' 追加
permissions = permissions Or Permission.Execute
' 削除
permissions = permissions And Not Permission.Write
' 切り替え
permissions = permissions Xor Permission.Execute
' 文字列表現
Console.WriteLine(permissions.ToString()) ' "Read, Execute"
15.4 Enumのメソッド
PHP
<?php
enum Color: string {
case Red = 'red';
case Green = 'green';
case Blue = 'blue';
// メソッド
public function label(): string {
return match($this) {
self::Red => '赤',
self::Green => '緑',
self::Blue => '青',
};
}
// 静的メソッド
public static function primary(): array {
return [self::Red, self::Green, self::Blue];
}
// 定数
public const DEFAULT = self::Red;
}
echo Color::Red->label(); // "赤"
TypeScript
// enumにはメソッドを追加できない
// クラスまたはオブジェクトで代替
const Color = {
Red: 'red',
Green: 'green',
Blue: 'blue',
label(color: string): string {
const labels: Record<string, string> = {
red: '赤',
green: '緑',
blue: '青'
};
return labels[color] || '';
}
} as const;
type Color = typeof Color[keyof typeof Color];
console.log(Color.label(Color.Red)); // "赤"
// またはクラスベース
class ColorEnum {
static readonly Red = new ColorEnum('red', '赤');
static readonly Green = new ColorEnum('green', '緑');
static readonly Blue = new ColorEnum('blue', '青');
private constructor(
public readonly value: string,
public readonly label: string
) {}
static values(): ColorEnum[] {
return [ColorEnum.Red, ColorEnum.Green, ColorEnum.Blue];
}
}
VB.NET
' 拡張メソッドでメソッドを追加
Enum Color
Red
Green
Blue
End Enum
Module ColorExtensions
<Extension()>
Public Function Label(color As Color) As String
Select Case color
Case Color.Red : Return "赤"
Case Color.Green : Return "緑"
Case Color.Blue : Return "青"
Case Else : Return ""
End Select
End Function
<Extension()>
Public Function ToHexCode(color As Color) As String
Select Case color
Case Color.Red : Return "#FF0000"
Case Color.Green : Return "#00FF00"
Case Color.Blue : Return "#0000FF"
Case Else : Return ""
End Select
End Function
End Module
' 使用
Console.WriteLine(Color.Red.Label()) ' "赤"
Console.WriteLine(Color.Red.ToHexCode()) ' "#FF0000"
' より高度なパターン:クラスベース
Public Class SmartEnum
Public Shared ReadOnly Red As New SmartEnum("Red", "赤", "#FF0000")
Public Shared ReadOnly Green As New SmartEnum("Green", "緑", "#00FF00")
Public Shared ReadOnly Blue As New SmartEnum("Blue", "青", "#0000FF")
Public ReadOnly Property Name As String
Public ReadOnly Property Label As String
Public ReadOnly Property HexCode As String
Private Sub New(name As String, label As String, hexCode As String)
Me.Name = name
Me.Label = label
Me.HexCode = hexCode
End Sub
Public Shared Function Values() As IEnumerable(Of SmartEnum)
Return {Red, Green, Blue}
End Function
End Class
15.5 Enumユーティリティ
型安全な変換
<?php
// PHP
function getStatus(int $value): ?Status {
return Status::tryFrom($value);
}
// 全ケースの検証
function isValidStatus(int $value): bool {
return Status::tryFrom($value) !== null;
}
// TypeScript
function isValidStatus(value: number): value is Status {
return Object.values(Status).includes(value);
}
// 文字列からの変換
function parseStatus(str: string): Status | undefined {
return (Status as any)[str];
}
// 型安全なキーの取得
type StatusKey = keyof typeof Status;
const keys = Object.keys(Status).filter(
k => isNaN(Number(k))
) as StatusKey[];
' VB.NET
Function TryParseStatus(value As Integer, ByRef result As Status) As Boolean
If [Enum].IsDefined(GetType(Status), value) Then
result = CType(value, Status)
Return True
End If
Return False
End Function
' 全ての値を取得
Function GetAllStatuses() As Status()
Return DirectCast([Enum].GetValues(GetType(Status)), Status())
End Function
' 名前と値のペアを取得
Function GetStatusDictionary() As Dictionary(Of String, Integer)
Return [Enum].GetValues(GetType(Status)).
Cast(Of Status)().
ToDictionary(Function(s) s.ToString(), Function(s) CInt(s))
End Function