プログラミング言語別テンプレートリテラル完全ガイド – 文字列補間の最新手法
テンプレートリテラル(文字列補間)は、現代のプログラミング言語において文字列内に変数や式を埋め込むための強力な機能です。従来の文字列連結やsprintf
形式のフォーマットと比較して、より読みやすく直感的なコードが書けます。この記事では、主要なプログラミング言語でのテンプレートリテラルの使い方を比較しながら詳しく解説します。
テンプレートリテラルとは
テンプレートリテラルは、文字列内に変数や式を直接埋め込むことができる文字列リテラルです。多くの言語で異なる記法が採用されていますが、基本的な概念は共通しています。
主な特徴
- 可読性の向上: 変数と文字列が一体化した直感的な記法
- パフォーマンス: 従来の文字列連結より高速
- 柔軟性: 複雑な式や関数呼び出しも可能
JavaScript – テンプレートリテラル
基本的な使い方
const name = "太郎";
const age = 25;
const message = `こんにちは、${name}さん!あなたは${age}歳ですね。`;
console.log(message); // こんにちは、太郎さん!あなたは25歳ですね。
式の評価
const x = 10, y = 20;
console.log(`計算結果: ${x} + ${y} = ${x + y}`); // 計算結果: 10 + 20 = 30
複数行文字列
const html = `
<div class="user">
<h2>${name}</h2>
<p>年齢: ${age}歳</p>
</div>
`;
関数呼び出し
function formatDate(date) {
return date.toLocaleDateString('ja-JP');
}
const today = new Date();
console.log(`今日は${formatDate(today)}です`);
タグ付きテンプレートリテラル
function highlight(strings, ...values) {
return strings.map((str, i) =>
str + (values[i] ? `<mark>${values[i]}</mark>` : '')
).join('');
}
const keyword = "JavaScript";
const result = highlight`プログラミング言語${keyword}を学習中です`;
Python – f-string
基本的な使い方
name = "花子"
age = 30
message = f"こんにちは、{name}さん!あなたは{age}歳ですね。"
print(message) # こんにちは、花子さん!あなたは30歳ですね。
フォーマット指定
pi = 3.14159
price = 1234567
print(f"円周率: {pi:.2f}") # 円周率: 3.14
print(f"価格: {price:,}円") # 価格: 1,234,567円
式の評価
x, y = 15, 25
print(f"結果: {x} × {y} = {x * y}") # 結果: 15 × 25 = 375
デバッグ用記法(Python 3.8+)
x = 42
y = 24
print(f"{x=}, {y=}, {x+y=}") # x=42, y=24, x+y=66
日付フォーマット
from datetime import datetime
now = datetime.now()
print(f"現在時刻: {now:%Y年%m月%d日 %H:%M:%S}")
C# – 文字列補間
基本的な使い方
string name = "次郎";
int age = 28;
string message = $"こんにちは、{name}さん!あなたは{age}歳ですね。";
Console.WriteLine(message);
フォーマット指定
double price = 1234.56;
DateTime now = DateTime.Now;
Console.WriteLine($"価格: {price:C}"); // 価格: ¥1,235
Console.WriteLine($"日時: {now:yyyy-MM-dd}"); // 日時: 2025-07-29
条件式
int score = 85;
string result = $"結果: {(score >= 60 ? "合格" : "不合格")}";
Console.WriteLine(result); // 結果: 合格
メソッド呼び出し
string text = "hello world";
Console.WriteLine($"大文字: {text.ToUpper()}"); // 大文字: HELLO WORLD
Raw文字列リテラル(C# 11+)
string json = $$"""
{
"name": "{{name}}",
"age": {{age}}
}
""";
Kotlin – 文字列テンプレート
基本的な使い方
val name = "三郎"
val age = 35
val message = "こんにちは、${name}さん!あなたは${age}歳ですね。"
println(message)
式の評価
val a = 10
val b = 20
println("計算: $a + $b = ${a + b}") // 計算: 10 + 20 = 30
プロパティアクセス
data class Person(val name: String, val age: Int)
val person = Person("四郎", 40)
println("${person.name}さんは${person.age}歳です")
関数呼び出し
fun formatCurrency(amount: Double): String = "¥${String.format("%,.0f", amount)}"
val price = 123456.0
println("価格: ${formatCurrency(price)}")
Swift – 文字列補間
基本的な使い方
let name = "五郎"
let age = 32
let message = "こんにちは、\(name)さん!あなたは\(age)歳ですね。"
print(message)
計算式
let width = 10
let height = 20
print("面積: \(width) × \(height) = \(width * height)")
オプショナル値の処理
let optionalName: String? = "六郎"
print("名前: \(optionalName ?? "不明")") // 名前: 六郎
カスタム文字列補間(Swift 5+)
extension String.StringInterpolation {
mutating func appendInterpolation(currency value: Double) {
appendLiteral(String(format: "¥%.0f", value))
}
}
let price = 1234.0
print("価格: \(currency: price)") // 価格: ¥1234
Rust – マクロによる文字列フォーマット
format!マクロ
let name = "七郎";
let age = 27;
let message = format!("こんにちは、{}さん!あなたは{}歳ですね。", name, age);
println!("{}", message);
名前付きパラメータ
let message = format!("こんにちは、{name}さん!あなたは{age}歳ですね。",
name="八郎", age=29);
println!("{}", message);
println!マクロでの直接出力
let x = 10;
let y = 20;
println!("計算: {} + {} = {}", x, y, x + y);
フォーマット指定
let pi = 3.14159;
let amount = 1234567;
println!("円周率: {:.2}", pi); // 円周率: 3.14
println!("金額: {:,}", amount); // 金額: 1,234,567(実装依存)
Ruby – 文字列補間
基本的な使い方
name = "九郎"
age = 31
message = "こんにちは、#{name}さん!あなたは#{age}歳ですね。"
puts message
式の評価
x, y = 15, 25
puts "計算: #{x} × #{y} = #{x * y}" # 計算: 15 × 25 = 375
メソッド呼び出し
text = "hello world"
puts "大文字: #{text.upcase}" # 大文字: HELLO WORLD
複雑な式
numbers = [1, 2, 3, 4, 5]
puts "合計: #{numbers.sum}, 平均: #{numbers.sum.to_f / numbers.length}"
Go – テンプレート
fmt.Sprintfを使用
package main
import "fmt"
func main() {
name := "十郎"
age := 26
message := fmt.Sprintf("こんにちは、%sさん!あなたは%d歳ですね。", name, age)
fmt.Println(message)
}
text/templateパッケージ
import (
"os"
"text/template"
)
const tmpl = `こんにちは、{{.Name}}さん!あなたは{{.Age}}歳ですね。`
type Person struct {
Name string
Age int
}
func main() {
t := template.Must(template.New("greeting").Parse(tmpl))
person := Person{Name: "十一郎", Age: 33}
t.Execute(os.Stdout, person)
}
Java – テキストブロックと文字列フォーマット
String.formatを使用
String name = "十二郎";
int age = 34;
String message = String.format("こんにちは、%sさん!あなたは%d歳ですね。", name, age);
System.out.println(message);
テキストブロック(Java 15+)
String name = "十三郎";
int age = 36;
String message = """
こんにちは、%sさん!
あなたは%d歳ですね。
""".formatted(name, age);
System.out.println(message);
MessageFormatクラス
import java.text.MessageFormat;
String pattern = "こんにちは、{0}さん!あなたは{1}歳ですね。";
String message = MessageFormat.format(pattern, "十四郎", 37);
System.out.println(message);
PHP – 文字列補間
ダブルクォート内での変数展開
$name = "十五郎";
$age = 38;
$message = "こんにちは、{$name}さん!あなたは{$age}歳ですね。";
echo $message;
sprintf関数
$message = sprintf("こんにちは、%sさん!あなたは%d歳ですね。", $name, $age);
echo $message;
Heredoc記法
$html = <<<HTML
<div class="user">
<h2>{$name}</h2>
<p>年齢: {$age}歳</p>
</div>
HTML;
各言語の比較表
言語 | 記法 | 特徴 | パフォーマンス |
---|---|---|---|
JavaScript | `${変数}` | 複数行対応、タグ付き | 高速 |
Python | f”{変数}” | フォーマット豊富、デバッグ機能 | 最高速 |
C# | $”{変数}” | 型安全、豊富なフォーマット | 高速 |
Kotlin | “${変数}” | Javaとの互換性 | 高速 |
Swift | \(変数) | 型安全、カスタム補間 | 高速 |
Rust | format!(“{}”, 変数) | 安全性、コンパイル時チェック | 高速 |
Ruby | “#{変数}” | 動的、柔軟 | 中速 |
Go | fmt.Sprintf(“%s”, 変数) | シンプル、効率的 | 高速 |
Java | String.format(“%s”, 変数) | プラットフォーム独立 | 中速 |
PHP | “{$変数}” | Web開発特化 | 中速 |
実践的な使用例
ログメッセージの生成
// JavaScript
const logLevel = "ERROR";
const timestamp = new Date().toISOString();
const message = "Database connection failed";
console.log(`[${timestamp}] ${logLevel}: ${message}`);
# Python
from datetime import datetime
log_level = "ERROR"
timestamp = datetime.now()
message = "Database connection failed"
print(f"[{timestamp:%Y-%m-%d %H:%M:%S}] {log_level}: {message}")
API レスポンスの生成
// C#
var userId = 123;
var userName = "田中";
var json = $@"{{
""userId"": {userId},
""userName"": ""{userName}"",
""timestamp"": ""{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ssZ}""
}}";
SQL クエリの構築
// Kotlin
fun buildSelectQuery(table: String, columns: List<String>, condition: String): String {
val columnList = columns.joinToString(", ")
return "SELECT $columnList FROM $table WHERE $condition"
}
HTML テンプレートの生成
// Swift
func generateUserCard(name: String, age: Int, email: String) -> String {
return """
<div class="user-card">
<h3>\(name)</h3>
<p>年齢: \(age)歳</p>
<p>メール: \(email)</p>
</div>
"""
}
パフォーマンス比較
ベンチマークテスト結果
// JavaScript - 100万回実行
const name = "テスト";
const age = 25;
console.time('Template Literal');
for(let i = 0; i < 1000000; i++) {
const result = `Hello, ${name}! Age: ${age}`;
}
console.timeEnd('Template Literal'); // 約50ms
console.time('String Concatenation');
for(let i = 0; i < 1000000; i++) {
const result = "Hello, " + name + "! Age: " + age;
}
console.timeEnd('String Concatenation'); // 約80ms
メモリ使用量の考慮
# Python - メモリ効率の比較
import sys
name = "テスト"
age = 25
# f-string
f_string_result = f"Hello, {name}! Age: {age}"
print(f"f-string size: {sys.getsizeof(f_string_result)} bytes")
# 文字列連結
concat_result = "Hello, " + name + "! Age: " + str(age)
print(f"concat size: {sys.getsizeof(concat_result)} bytes")
セキュリティの考慮事項
SQLインジェクション対策
# 危険な例(絶対に避ける)
user_input = "'; DROP TABLE users; --"
# query = f"SELECT * FROM users WHERE name = '{user_input}'" # 危険!
# 安全な例
import sqlite3
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE name = ?", (user_input,))
XSS対策
// 危険な例
const userInput = '<script>alert("XSS")</script>';
// document.innerHTML = `<div>${userInput}</div>`; // 危険!
// 安全な例
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
document.innerHTML = `<div>${escapeHtml(userInput)}</div>`;
ベストプラクティス
1. 読みやすさを重視
// TypeScript - 良い例
interface User {
name: string;
age: number;
email: string;
}
function formatUserInfo(user: User): string {
return `
ユーザー情報:
名前: ${user.name}
年齢: ${user.age}歳
メール: ${user.email}
`.trim();
}
2. 長い文字列の適切な分割
// C# - 良い例
public string GenerateEmailTemplate(string name, string product, decimal price)
{
return $@"
{name}様
ご購入いただいた商品「{product}」({price:C})の
発送手続きが完了いたしました。
お問い合わせ: support@example.com
".Trim();
}
3. 国際化対応
// Kotlin - 多言語対応
class MessageFormatter(private val locale: String) {
fun formatGreeting(name: String): String {
return when(locale) {
"ja" -> "こんにちは、${name}さん!"
"en" -> "Hello, $name!"
"es" -> "¡Hola, $name!"
else -> "Hello, $name!"
}
}
}
将来のトレンド
新しい言語での実装
// Rust - 将来的な文字列補間構文(提案段階)
let name = "Rust";
let version = "1.70";
// println!("Language: {name}, Version: {version}"); // 将来の可能性
型安全な文字列補間
// TypeScript - テンプレートリテラル型
type EmailTemplate = `Hello, ${string}! Your order #${number} is ready.`;
function sendEmail(template: EmailTemplate) {
// 型安全なテンプレート処理
}
sendEmail("Hello, John! Your order #12345 is ready."); // OK
// sendEmail("Invalid template"); // Error
まとめ
テンプレートリテラルは現代のプログラミングにおいて不可欠な機能となっています。各言語で記法は異なりますが、基本的な概念と利点は共通しています。
主な利点:
- 可読性の向上: 変数と文字列の自然な結合
- パフォーマンス: 従来の文字列連結より高速
- 保守性: コードの理解と修正が容易
- 安全性: 型チェックやエスケープ機能
選択の指針:
- JavaScript/TypeScript: Webフロントエンド、Node.js開発
- Python: データサイエンス、機械学習、Web開発
- C#: Windowsアプリケーション、Web API
- Kotlin: Androidアプリ、サーバーサイド
- Swift: iOSアプリ開発
- Rust: システムプログラミング、高性能アプリケーション
どの言語を使用する場合でも、セキュリティを考慮し、適切なエスケープ処理を行うことが重要です。また、パフォーマンスが重要な場面では、各言語の特性を理解して最適な手法を選択しましょう。
参考リンク
- MDN – Template Literals (JavaScript)
- Python PEP 498 – Literal String Interpolation
- Microsoft Docs – String Interpolation (C#)
- Kotlin Documentation – String Templates
- Swift Documentation – String Interpolation
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座