Pattern matching is a major feature in software development. パターン matching is applicable in several locations. パターン matching is a major feature in software development. パターン matching is applicable in several locations. パターン matching is a major feature in software development. パターン matching is applicable in several locations. 私はこの投稿で私が知っているプログラミング言語のいくつかでパターン一致のパワーを比較したいと思います。 switch case すべての読者は、そのことを知っていると私は思います。 Cから相続したシンタクス: In short: switch case The switch clause refers to a value-return statement. The switch clause refers to a value-returning statement. The switch clause refers to a value-returning statement. 各ケースの文は別の文を設定します; 値が文に一致すると、関連ブロックが実行されます。 case clauses are evaluated in order. The first clause that matches gets its block executed. 最初に一致する clauseは、そのブロックが実行されます。 .In C, case clauses are fall-through; you need to explicitly break to escape the switch, otherwise, the next case is evaluated. C では、ケースの条項は落下し、スイッチを逃れるために明示的に破る必要があります。 Javaのパターンマッチング 私がプロの文脈で使った最初のプログラミング言語であるJavaから始めます。 Javaのパターンマッチングは、そのバージョン全体で大きく進化しました. Here is the "official" sample for version 23, slightly modified. It defines several 実施とA 周囲を評価する方法は、確かに オブジェクト指向プログラミングの良い例です。 Shape static not interface Shape { } record Rectangle(double length, double width) implements Shape { } record Circle(double radius) implements Shape { } public class Main { static double getPerimeter(Shape s) throws IllegalArgumentException { return switch (s) { //1 case Rectangle r when r.length() == r.width() -> { //2 System.out.println("Square detected"); yield 4 * r.length(); } case Rectangle r -> //3 2 * r.length() + 2 * r.width(); case Circle c -> //4 2 * c.radius() * Math.PI; default -> //5 throw new IllegalArgumentException("Unrecognized shape"); }; } } Shape Parameter as s を参照する s が直角であり、直角が平方であるかどうかを評価する。 s が Rectangle であるかを評価する s がサークルであるかを評価する 前項のいずれも一致しない場合は、例外を投げるためにデフォルト このJavaバージョンは私たちのベースラインになります。 新しい人の特徴 シンタックス スイッチ スイッチ The new syntax has some advantages over the legacy non-pile. 新しいシンタクスは、遺産非矢印に比べていくつかの利点があります。 Cから相続する。 switch Cスタイル タイトル: Once the runtime has executed a ブロック, it runs next block. To avoid it, you need to set a あまり良くない古い時代に、一部の開発者はコードの重複を避けるためにこの機能を利用しました。 case case case break しかし、経験は、潜在的なバグの原因があまりにも多かったことを示しています:現代のコーディングの慣行はそれを避ける傾向があります。 新しい矢印の構文では、ランタイムは適切な値のみを評価します。 ブロック break case Cスタイル セクションは単純な値のみを評価します。コミュニティは、Java 7 が String 値を許可したときに大きな恩恵を祝いました。Java 21 はさらに進みました:矢印の構文と併せて、タイプを切り替えることを可能にしました。 タイプ case Shape さらに、クラスに変更する場合 クラスの階層構造が、 , コンパイラは自動的に欠けているケースを検出することができます. 最後に、バージョン24は追加のオプションを追加しました。 フィルター そして sealed when Flip 側では、古い C 文法では、ランタイムは正しい方向に直接ジャンプします。 The new arrow syntax evaluates them sequentially, exactly as if with 声明 case if else 次のセクションでは、コードを他の言語にポートします。 Scalaのパターンマッチング Scalaのパターンマッチングは、創業以来、二番目にありませんでした. Kotlinはそれから多くのインスピレーションを引き出しました。 trait Shape case class Rectangle(length: Double, width: Double) extends Shape case class Circle(radius: Double) extends Shape def getPerimeter(s: Shape) = { s match { //1 case Rectangle(length, width) if length == width => //2-3 println("Square detected") 4 * length case Rectangle(length, width) => 2 * length + 2 * width //3-4 case Circle(radius) => 2 * radius * Math.PI //3-5 case _ => throw new IllegalArgumentException("Unrecognized shape") //6 } } S 参照を直接使用する s が直角であり、直角が平方であるかどうかを評価する。 Scala additionally matches the class attributes クラス属性 s が Rectangle であるかを評価する s がサークルであるかを評価する 前項のいずれも一致しない場合は、例外を投げるためにデフォルト Kotlinのパターンマッチング Java のコードを Kotlin に翻訳してみましょう。 ACTIVATE THE コンピュータで描かれた特徴 . モス 実験 Xwhen-guards シェイプ371 interface Shape data class Rectangle(val length: Double, val width: Double): Shape data class Circle(val radius: Double): Shape fun getPerimeter(s: Shape) = when (s) { //1 is Rectangle if s.length == s.width -> { //2 println("Square detected") 4 * s.length } is Rectangle -> 2 * s.length + 2 * s.width //3 is Circle -> 2 * s.radius * Math.PI //4 else -> throw IllegalArgumentException("Unknown shape") //5 } } Shape Parameter as s を参照する s が直角であり、直角の幅がその高さに等しいかどうかを評価する s が Rectangle であるかを評価する s がサークルであるかを評価する 前項のいずれも一致しない場合は、例外を投げるためにデフォルト Kotlinのパターンマッチングは、Javaのパターンと大きく似ていますが、シンタクスにわずかな変更があります。 で、 代替 . エジ if when パターンマッチングにおけるKotlin vs. Javaの比較的進化はかなり明らかである。Javaは古代Cシンタクスに遅れており、Kotlinはすでに最初からコンクリートタイプに匹敵することができた。2020年にはJava 14が矢印オペレーターとのギャップを縮小し、1年後にはJava 16がコンクリートタイプに匹敵する能力でギャップを完全に閉じた。 条項 when Kotlinの実験的性質 つまり、JavaはJavaを超えています!少なくともこの分野では珍しいことです。 if Pythonのパターンマッチング 以前、Python は、Python に似たものを提供しませんでした。 バージョン 3.10 から、エレガントな方法で同じ機能を提供しています: switch class Shape: pass class Rectangle(Shape): def __init__(self, length: float, width: float): self.length = length self.width = width class Circle(Shape): def __init__(self, radius: float): self.radius = radius def get_perimeter(s: Shape) -> float: match s: case Rectangle(length=l, width=w) if l == w: print("Square detected") return 4 * l case Rectangle(length=l, width=w): return 2 * l + 2 * w case Circle(radius=r): return 2 * pi * r case _: raise ValueError("Unknown shape") ランタイムは評価 JVM 言語と同様に、順序的に条項を設定します。 case Rustのパターンマッチング Rustのメモリ管理のアプローチは、チェックタイプではよくありません。 Structures are structured data placeholders; their memory size is known at compile time. 構造は構造化されたデータの場所保持者であり、そのメモリのサイズはコンパイル時に知られる。 Traits are contracts, similar to interfaces. 特性は、インターフェイスに似た契約である。 You can provide a implementation of a trait for a structure. 構造の実装を提供することができます。 Referencing a variable by its trait has consequences. Since the reference can point to structures of different sizes, the compiler can not know its size at compile-time and must place the variable on the heap instead of the stack. 参照が異なるサイズの構造を指し示すことができるので、コンパイラはコンパイル時にそのサイズを知ることができません。 オリジナルJavaはポリモルフィズムを活用しません;それは素晴らしいものではありません。Rustでは、それはさらに醜いです。Rustはオブジェクト指向のプログラミング言語ではありませんが、それはポリモルフィズムを使用することを導きます。 警告:私は以下のコードを推奨しませんし、それとの関連を否定します! trait Shape: Any { fn as_any(&self) -> &dyn Any; //1 } struct Circle { radius: f64, } struct Rectangle { width: f64, height: f64, } impl Shape for Circle { fn as_any(&self) -> &dyn Any { //2 self } } impl Shape for Rectangle { fn as_any(&self) -> &dyn Any { //2 self } } fn get_perimeter(s: Box<dyn Shape>) -> f64 { match s.as_any() { //3 any if any.is::<Rectangle>() => { //4 let rectangle = any.downcast_ref::<Rectangle>().unwrap(); //5 if rectangle.width == rectangle.height { println!("Square matched"); 4.0 * rectangle.width } else { 2.0 * (rectangle.width + rectangle.height) } } any if any.is::<Circle>() => { //4 let circle = any.downcast_ref::<Circle>().unwrap(); //5 2.0 * std::f64::consts::PI * circle.radius } _ => panic!() } } Rustのタイプシステムは、変数のタイプを得る方法を提供しません。 構造のための機能の実装 Match on the underlying structure type 基礎構造の種類 タイプチェック Downcast to the underlying structure to use its fields (そのフィールドを使用するために基礎構造にダウンロード) この上記の人工コードポートは、Rust のパターンマッチング能力を誤って表しています。 . いろんな場所 結論 この投稿で説明されたすべての言語の中で、Scalaはパターンマッチングを提供する最初の言語でした。 長年にわたり、それは他の人々が追い詰めようとしていたグラルであり、KotlinとJavaはついにこの段階に達しました。 switch JVM 以外では、Python と Rust はパターン マッチングの強力な機能を備えています。 パターンマッチングは、読み取り可能で維持可能なコードを書きたい開発者にとって大きな助けとなる。 この記事の完全なソースコードはこちらでご覧いただけます。 . GitHub To go further: Java 23 でのパターン matching パターン matching in Kotlin パターン matching in scala タイトル: Match statement in Python パターン matching in Rust オリジナルの投稿 A Java Geek on 20th July, 2025 ・Java Geek