第4章 変数と定数
4.1 変数宣言
PHP
<?php
// 変数は $ で始まる
$name = "John";
$age = 30;
// 型宣言(PHP 7.4+ クラスプロパティ)
class User {
public string $name;
public int $age;
public ?string $email = null; // Nullable
}
// 変数の破棄
unset($name);
TypeScript
// let - 再代入可能
let name = "John";
name = "Jane"; // OK
// const - 再代入不可
const age = 30;
// age = 31; // エラー
// var - 関数スコープ(非推奨)
var oldStyle = "legacy";
// 型注釈
let userName: string = "John";
const userAge: number = 30;
VB.NET
' Dim - 変数宣言
Dim name As String = "John"
Dim age As Integer = 30
' 複数変数の宣言
Dim x, y, z As Integer ' すべて Integer
Dim a As Integer, b As String ' 異なる型
' 型推論(Option Infer On)
Dim inferred = "Hello" ' String と推論
' 静的変数(メソッド内で値を保持)
Sub Counter()
Static count As Integer = 0
count += 1
Console.WriteLine(count)
End Sub
4.2 定数宣言
PHP
<?php
// define 関数
define('MAX_SIZE', 100);
define('CONFIG', ['key' => 'value']); // PHP 7.0+ 配列対応
// const キーワード(クラス内または名前空間トップレベル)
const VERSION = '1.0.0';
class Config {
public const MAX_SIZE = 100;
private const SECRET = 'hidden';
// PHP 8.1+ final const
final public const IMMUTABLE = 'cannot override';
}
echo Config::MAX_SIZE;
TypeScript
// const 変数
const MAX_SIZE = 100;
const CONFIG = { key: 'value' } as const; // readonly
// enum
enum Color {
Red = 1,
Green = 2,
Blue = 3,
}
// const enum(コンパイル時にインライン化)
const enum Direction {
Up,
Down,
Left,
Right,
}
// クラス内 readonly
class Config {
static readonly MAX_SIZE = 100;
readonly instanceValue: number;
constructor(value: number) {
this.instanceValue = value;
}
}
VB.NET
' Const - コンパイル時定数
Const MAX_SIZE As Integer = 100
Const VERSION As String = "1.0.0"
' クラス内定数
Class Config
Public Const MAX_SIZE As Integer = 100
Private Const SECRET As String = "hidden"
' ReadOnly - 実行時定数(コンストラクタで設定可能)
Public ReadOnly CreatedAt As DateTime
Public Sub New()
CreatedAt = DateTime.Now
End Sub
End Class
' Shared ReadOnly(静的な実行時定数)
Class AppConfig
Public Shared ReadOnly Instance As New AppConfig()
End Class
' 使用
Console.WriteLine(Config.MAX_SIZE)
4.3 スコープ
ブロックスコープ vs 関数スコープ
| 言語 | デフォルトスコープ | ブロックスコープ |
|---|---|---|
| PHP | 関数スコープ | なし |
| TypeScript | let/const: ブロック、var: 関数 | あり |
| VB.NET | ブロックスコープ | あり |
PHP
<?php
function example()
{
if (true) {
$x = 10; // 関数スコープ
}
echo $x; // 10(アクセス可能)
}
// グローバル変数
$global = "I'm global";
function useGlobal() {
global $global; // global キーワードが必要
echo $global;
// または $GLOBALS
echo $GLOBALS['global'];
}
TypeScript
function example() {
if (true) {
let x = 10; // ブロックスコープ
var y = 20; // 関数スコープ
const z = 30; // ブロックスコープ
}
// console.log(x); // エラー
console.log(y); // 20(アクセス可能)
// console.log(z); // エラー
}
// モジュールスコープ
const moduleVar = "module level";
export const exported = "exported";
VB.NET
Sub Example()
If True Then
Dim x As Integer = 10 ' ブロックスコープ
End If
' Console.WriteLine(x) ' エラー:アクセス不可
' ただしループ変数は注意
For i As Integer = 0 To 10
' i はここでのみ有効
Next
' Console.WriteLine(i) ' エラー
End Sub
' モジュールレベル変数
Module Module1
Private moduleVar As String = "module level"
Public publicVar As String = "public"
End Module
4.4 ホイスティング
PHP
<?php
// PHP には変数のホイスティングはない
// echo $x; // 警告:未定義の変数
$x = 10;
// 関数はホイスティングされる
sayHello(); // OK
function sayHello() {
echo "Hello";
}
TypeScript
// var はホイスティングされる
console.log(x); // undefined(エラーではない)
var x = 10;
// let/const はホイスティングされるがTDZ
// console.log(y); // ReferenceError
let y = 10;
// 関数宣言はホイスティングされる
sayHello(); // OK
function sayHello() {
console.log("Hello");
}
// 関数式はホイスティングされない
// greet(); // エラー
const greet = () => console.log("Hi");
VB.NET
' VB.NET にはホイスティングの概念はない
' 変数は宣言後に使用可能
' Console.WriteLine(x) ' エラー
Dim x As Integer = 10
' メソッドは定義位置に関係なく呼び出せる(コンパイラが解決)
Sub Main()
SayHello() ' OK(下で定義されていても)
End Sub
Sub SayHello()
Console.WriteLine("Hello")
End Sub
4.5 参照型と値型
PHP
<?php
// スカラー型は値渡し
$a = 10;
$b = $a;
$b = 20;
echo $a; // 10
// 配列は値渡し(コピーオンライト)
$arr1 = [1, 2, 3];
$arr2 = $arr1;
$arr2[] = 4;
print_r($arr1); // [1, 2, 3]
// オブジェクトは参照渡し
$obj1 = new stdClass();
$obj1->name = "John";
$obj2 = $obj1;
$obj2->name = "Jane";
echo $obj1->name; // Jane
// 明示的な参照
$x = 10;
$y = &$x;
$y = 20;
echo $x; // 20
TypeScript
// プリミティブは値渡し
let a = 10;
let b = a;
b = 20;
console.log(a); // 10
// オブジェクト・配列は参照渡し
const arr1 = [1, 2, 3];
const arr2 = arr1;
arr2.push(4);
console.log(arr1); // [1, 2, 3, 4]
const obj1 = { name: "John" };
const obj2 = obj1;
obj2.name = "Jane";
console.log(obj1.name); // Jane
// シャローコピー
const arrCopy = [...arr1];
const objCopy = { ...obj1 };
// ディープコピー
const deepCopy = structuredClone(obj1);
VB.NET
' 値型(スタックに格納)
Dim a As Integer = 10
Dim b As Integer = a
b = 20
Console.WriteLine(a) ' 10
' 構造体も値型
Structure Point
Public X As Integer
Public Y As Integer
End Structure
Dim p1 As New Point With {.X = 1, .Y = 2}
Dim p2 As Point = p1
p2.X = 10
Console.WriteLine(p1.X) ' 1
' 参照型(ヒープに格納)
Class Person
Public Name As String
End Class
Dim person1 As New Person With {.Name = "John"}
Dim person2 As Person = person1
person2.Name = "Jane"
Console.WriteLine(person1.Name) ' Jane
' 配列は参照型
Dim arr1() As Integer = {1, 2, 3}
Dim arr2() As Integer = arr1
arr2(0) = 10
Console.WriteLine(arr1(0)) ' 10
' 配列のコピー
Dim arrCopy(arr1.Length - 1) As Integer
Array.Copy(arr1, arrCopy, arr1.Length)
値型と参照型の一覧
| VB.NET | 分類 | 備考 |
|---|---|---|
Integer, Long, Double 等 |
値型 | 数値型 |
Boolean |
値型 | |
Date |
値型 | |
Structure |
値型 | ユーザー定義 |
Enum |
値型 | |
String |
参照型 | ただし不変なので値型のように振る舞う |
Class |
参照型 | |
Array |
参照型 | |
Interface |
参照型 | |
Delegate |
参照型 |