第6章 制御構造
6.1 条件分岐
if文
PHP
<?php
if ($condition) {
// 処理
} elseif ($otherCondition) {
// 処理
} else {
// 処理
}
// 代替構文(テンプレート向け)
if ($condition):
// 処理
elseif ($otherCondition):
// 処理
else:
// 処理
endif;
TypeScript
if (condition) {
// 処理
} else if (otherCondition) {
// 処理
} else {
// 処理
}
// 型ガード
if (typeof value === "string") {
// value は string 型として扱われる
}
if (value instanceof Date) {
// value は Date 型として扱われる
}
VB.NET
If condition Then
' 処理
ElseIf otherCondition Then
' 処理
Else
' 処理
End If
' 単一行 If
If condition Then DoSomething()
' 単一行 If-Else
If condition Then DoA() Else DoB()
' 型チェック
If TypeOf obj Is String Then
Dim s As String = CStr(obj)
End If
switch/Select Case
PHP
<?php
switch ($value) {
case 1:
echo "One";
break;
case 2:
case 3:
echo "Two or Three";
break;
default:
echo "Other";
}
// match 式(PHP 8.0+)
$result = match($value) {
1 => "One",
2, 3 => "Two or Three",
default => "Other",
};
// match は厳密比較を使用
$result = match(true) {
$age < 18 => "Minor",
$age < 65 => "Adult",
default => "Senior",
};
TypeScript
switch (value) {
case 1:
console.log("One");
break;
case 2:
case 3:
console.log("Two or Three");
break;
default:
console.log("Other");
}
// 網羅性チェック(never型)
type Color = "red" | "green" | "blue";
function getColorCode(color: Color): string {
switch (color) {
case "red":
return "#FF0000";
case "green":
return "#00FF00";
case "blue":
return "#0000FF";
default:
const _exhaustive: never = color;
return _exhaustive;
}
}
VB.NET
Select Case value
Case 1
Console.WriteLine("One")
Case 2, 3
Console.WriteLine("Two or Three")
Case 4 To 10
Console.WriteLine("Four to Ten")
Case Is > 10
Console.WriteLine("Greater than Ten")
Case Else
Console.WriteLine("Other")
End Select
' 文字列の Select Case
Select Case name.ToLower()
Case "john", "jane"
Console.WriteLine("Known name")
Case Else
Console.WriteLine("Unknown")
End Select
' 条件式も可能
Select Case True
Case age < 18
Console.WriteLine("Minor")
Case age < 65
Console.WriteLine("Adult")
Case Else
Console.WriteLine("Senior")
End Select
6.2 ループ
for ループ
PHP
<?php
for ($i = 0; $i < 10; $i++) {
echo $i;
}
// 複数の変数
for ($i = 0, $j = 10; $i < $j; $i++, $j--) {
echo "$i, $j\n";
}
TypeScript
for (let i = 0; i < 10; i++) {
console.log(i);
}
// for...of(イテラブル)
const arr = [1, 2, 3];
for (const value of arr) {
console.log(value);
}
// for...in(プロパティキー)
const obj = { a: 1, b: 2 };
for (const key in obj) {
console.log(key);
}
VB.NET
For i As Integer = 0 To 9
Console.WriteLine(i)
Next
' ステップ指定
For i As Integer = 0 To 10 Step 2
Console.WriteLine(i) ' 0, 2, 4, 6, 8, 10
Next
' 逆順
For i As Integer = 10 To 0 Step -1
Console.WriteLine(i)
Next
' Next に変数を指定(可読性向上)
For i As Integer = 0 To 9
Console.WriteLine(i)
Next i
foreach ループ
PHP
<?php
$arr = [1, 2, 3];
foreach ($arr as $value) {
echo $value;
}
foreach ($arr as $key => $value) {
echo "$key: $value\n";
}
// 参照渡し(配列を変更)
foreach ($arr as &$value) {
$value *= 2;
}
unset($value); // 参照を解除(重要)
// 連想配列
$dict = ['a' => 1, 'b' => 2];
foreach ($dict as $key => $value) {
echo "$key: $value\n";
}
TypeScript
const arr = [1, 2, 3];
// for...of
for (const value of arr) {
console.log(value);
}
// forEach メソッド
arr.forEach((value, index) => {
console.log(`${index}: ${value}`);
});
// Map
const map = new Map([["a", 1], ["b", 2]]);
for (const [key, value] of map) {
console.log(`${key}: ${value}`);
}
// Object.entries
const obj = { a: 1, b: 2 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key}: ${value}`);
}
VB.NET
Dim arr() As Integer = {1, 2, 3}
For Each value As Integer In arr
Console.WriteLine(value)
Next
' Dictionary
Dim dict As New Dictionary(Of String, Integer) From {
{"a", 1},
{"b", 2}
}
For Each kvp In dict
Console.WriteLine($"{kvp.Key}: {kvp.Value}")
Next
' LINQ と組み合わせ
For Each item In arr.Where(Function(x) x > 1)
Console.WriteLine(item)
Next
while ループ
PHP
<?php
$i = 0;
while ($i < 10) {
echo $i;
$i++;
}
// do-while
$j = 0;
do {
echo $j;
$j++;
} while ($j < 10);
TypeScript
let i = 0;
while (i < 10) {
console.log(i);
i++;
}
// do-while
let j = 0;
do {
console.log(j);
j++;
} while (j < 10);
VB.NET
Dim i As Integer = 0
While i < 10
Console.WriteLine(i)
i += 1
End While
' Do While(前判定)
Dim j As Integer = 0
Do While j < 10
Console.WriteLine(j)
j += 1
Loop
' Do Until(条件が真になるまで)
Dim k As Integer = 0
Do Until k >= 10
Console.WriteLine(k)
k += 1
Loop
' Do...Loop While(後判定)
Dim l As Integer = 0
Do
Console.WriteLine(l)
l += 1
Loop While l < 10
' Do...Loop Until
Dim m As Integer = 0
Do
Console.WriteLine(m)
m += 1
Loop Until m >= 10
ループ制御
| 制御 | PHP | TypeScript | VB.NET |
|---|---|---|---|
| 中断 | break |
break |
Exit For/While/Do |
| 次へ | continue |
continue |
Continue For/While/Do |
| ラベル付き中断 | なし | ラベル付き |
GoTo(非推奨) |
PHP
<?php
for ($i = 0; $i < 10; $i++) {
if ($i == 5) continue;
if ($i == 8) break;
echo $i;
}
// ネストしたループからの脱出
for ($i = 0; $i < 3; $i++) {
for ($j = 0; $j < 3; $j++) {
if ($j == 1) break 2; // 外側のループも脱出
}
}
TypeScript
for (let i = 0; i < 10; i++) {
if (i === 5) continue;
if (i === 8) break;
console.log(i);
}
// ラベル付きループ
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (j === 1) break outer;
}
}
VB.NET
For i As Integer = 0 To 9
If i = 5 Then Continue For
If i = 8 Then Exit For
Console.WriteLine(i)
Next
' ネストしたループからの脱出
Dim found As Boolean = False
For i As Integer = 0 To 2
For j As Integer = 0 To 2
If j = 1 Then
found = True
Exit For ' 内側のループのみ脱出
End If
Next
If found Then Exit For ' 外側も脱出
Next
6.3 例外処理
PHP
<?php
try {
throw new Exception("Error message");
} catch (InvalidArgumentException $e) {
echo "Invalid argument: " . $e->getMessage();
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
} finally {
echo "Cleanup";
}
// PHP 8.0+: catch without variable
try {
// ...
} catch (NotFoundException) {
// $e を使わない場合
}
// カスタム例外
class CustomException extends Exception {
public function __construct(string $message, public readonly int $errorCode) {
parent::__construct($message);
}
}
TypeScript
try {
throw new Error("Error message");
} catch (e) {
if (e instanceof Error) {
console.log("Error:", e.message);
}
} finally {
console.log("Cleanup");
}
// カスタムエラー
class CustomError extends Error {
constructor(message: string, public readonly errorCode: number) {
super(message);
this.name = "CustomError";
}
}
// 型の絞り込み
try {
// ...
} catch (e: unknown) {
if (e instanceof CustomError) {
console.log(e.errorCode);
}
}
VB.NET
Try
Throw New Exception("Error message")
Catch ex As ArgumentException
Console.WriteLine("Invalid argument: " & ex.Message)
Catch ex As Exception
Console.WriteLine("Error: " & ex.Message)
Finally
Console.WriteLine("Cleanup")
End Try
' When 句(条件付きキャッチ)
Try
Throw New Exception("Error 42")
Catch ex As Exception When ex.Message.Contains("42")
Console.WriteLine("Caught 42 error")
Catch ex As Exception
Console.WriteLine("Other error")
End Try
' カスタム例外
Public Class CustomException
Inherits Exception
Public ReadOnly Property ErrorCode As Integer
Public Sub New(message As String, errorCode As Integer)
MyBase.New(message)
Me.ErrorCode = errorCode
End Sub
End Class
6.4 パターンマッチング
PHP 8.0+ match式
<?php
$result = match($value) {
0 => "Zero",
1, 2 => "One or Two",
default => "Other",
};
// 条件式
$category = match(true) {
$age < 13 => "Child",
$age < 20 => "Teen",
$age < 65 => "Adult",
default => "Senior",
};
TypeScript パターンマッチング(型ガード)
// Discriminated Union
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rectangle"; width: number; height: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "rectangle":
return shape.width * shape.height;
}
}
// カスタム型ガード
function isString(value: unknown): value is string {
return typeof value === "string";
}
// in 演算子による型絞り込み
interface Cat { meow(): void; }
interface Dog { bark(): void; }
function speak(animal: Cat | Dog) {
if ("meow" in animal) {
animal.meow();
} else {
animal.bark();
}
}
VB.NET パターンマッチング
' Select Case の拡張的使用
Select Case True
Case TypeOf obj Is String
Console.WriteLine("String")
Case TypeOf obj Is Integer
Console.WriteLine("Integer")
Case Else
Console.WriteLine("Other")
End Select
' TryCast による型チェック
Dim str As String = TryCast(obj, String)
If str IsNot Nothing Then
Console.WriteLine(str.Length)
End If
' .NET 7+(VB.NET での利用は限定的)
' C# のパターンマッチングほど高度ではない