Slide 1

Slide 1 text

JEP 455: Primitive Types in Patterns, instanceof, and switch (Preview) 2024/09/12 JJUGナイトセミナー

Slide 2

Slide 2 text

Θͨ͠ • Α͜ͳ☕ !JIDPNFHB • ʰ͍ͪ͹Μ΍͍͞͠(JU(JU)VCͷڭՊॻʱ • ΞϝϦΧ͔Βؼࠃ͠೥ʂ • ࢲ΋΂ΖΜ΂ΖΜʹͳΔͷ͕޷͖ ʢ++6(װࣄͷօ͞Μ͢Έ·ͤΜʣ 2

Slide 3

Slide 3 text

ࠓ೔ͷςʔϚ͸ ύλʔϯϚον🤝 3 コードを書くときの 機能を改善する取り組み Project Amberの⼀部

Slide 4

Slide 4 text

ࢹ֮తʹίʔυͷมԽΛݟͯ ڵຯΛ͍͖͍࣋ͬͯͨͩͨʂ 4

Slide 5

Slide 5 text

ίϯύΠϥͷ͓ؾ࣋ͪͱ͔͸ આ໌Ͱ͖ͳ͍ͷͰ ѱ͔͠Βͣʜ 5

Slide 6

Slide 6 text

ύλʔϯϚονͱ͸ Ұൠ࿦ • ෼͔Γ΍͘͢ݴ͏ͱ৚݅൑ఆͷͻͱͭ • ஋Λύλʔϯͱর߹͠ɺҰக Ϛον ͢Δ͔֬ೝ͢Δ • Ұக͔ͨ͠Ͳ͏͔Ͱ৚݅෼ذ͕Ͱ͖Δ͚ͩͰͳ͘ɺɹɹɹɹɹ ஋Λ෼ղͯ͠࢖͏͜ͱ͕Ͱ͖Δ 6

Slide 7

Slide 7 text

ύλʔϯϚονͱ͸ Ұൠ࿦ “Ն” “य़” “Ն” “ळ” “ౙ” 7

Slide 8

Slide 8 text

ύλʔϯϚονͱ͸ Ұൠ࿦ 🌻🌹🌸🌷 🌸🌸🌸🌸 🌷🌹🌻🌸 🌻🌹🌸🌷 🌻🌹❓ ❓ 💐💐💐💐 8

Slide 9

Slide 9 text

ύλʔϯϚονͱ͸ Ұൠ࿦ʣ 🌻🌹🌸🌷 🌻🌹❓🌷 Bʹ🌹 র߹ ෼ղ Cʹ🌸 9

Slide 10

Slide 10 text

γϯϓϧͳྫ String season = "Ն"; String result = switch (season) { ɹɹcase "य़" -> "Spring"; ɹɹcase "Ն" -> "Summer"; ɹɹcase "ळ" -> "Fall"; ɹɹcase "ౙ" -> "Winter"; ɹɹdefault -> "something wrong"; } 10 定数パターン というやつ

Slide 11

Slide 11 text

·ͣ͸ ύλʔϯϚονΛ ͔ͭ΋͏ 11

Slide 12

Slide 12 text

࢖͏ྫͷ঺հʢৄࡉ͸ޙ΄Ͳʣ 12 sealed interface UserAction permits Click, Drag, Scroll {} record Click(int x, int y) implements UserAction {} record Drag(int startX, int startY, int endX, int endY) implements UserAction {} record Scroll(int amount) implements UserAction {}

Slide 13

Slide 13 text

JOTUBODFPGͰύλʔϯϚον 13 if (action instanceof Click) { Click click = (Click) action; System.out.println("Clicked " + click.getX() + ", " + click.getY()); } if (action instanceof Click click) { System.out.println("Clicked " + click.getX() + ", " + click.getY()); } キャスト不要で 簡潔かつ安全

Slide 14

Slide 14 text

TXJUDIͰύλʔϯϚον 14 if (action instanceof Click) { Click c = (Click) action; result = "Clicked " + c.getX() + ", " + c.getY(); } else if (action instanceof Drag) { Drag d = (Drag) action; result = "Dragged " + d.startX() + " to " + d.endX(); } else if (action instanceof Scroll) { Scroll s = (Scroll) action; result = "Scrolled " + s.getAmount(); } else { result = "Unknown action"; }

Slide 15

Slide 15 text

TXJUDIͰύλʔϯϚον 15 String result = switch (action) { case Click c -> "Clicked " + c.x() + ", " + c.y(); case Drag d -> "Dragged " + d.startX() + " to " + d.endX(); case Scroll s -> "Scrolled " + s.amount(); }; オブジェクト型で パターンマッチ、 かなり簡潔! 判定と使⽤を 分けずに書ける タイプパターン というやつ パターン変数 スコープはマッチしたケースの中のみ

Slide 16

Slide 16 text

TXJUDIͰύλʔϯϚον 16 String result = switch (action) { case Click c -> "Clicked " + c.x() + ", " + c.y(); case Drag d -> "Dragged " + d.startX() + " to " + d.endX(); case Scroll s -> "Scrolled " + s.amount(); }; String result = switch (action) { case Click(int x, int y) -> "Clicked " + x + ", " + y; case Drag(int startX, int startY, int endX, int endY) -> "Dragged " + startX + " to " + endX; case Scroll(int amount) -> "Scrolled " + amount; }; Recordを使って 構造を活⽤ 値の分解も可能

Slide 17

Slide 17 text

3FDPSEɺγʔϧ 17 sealed interface UserAction permits Click, Drag, Scroll {} record Click(int x, int y) implements UserAction {} record Drag(int startX, int startY, int endX, int endY) implements UserAction {} record Scroll(int amount) implements UserAction {} Recordでクラス定義の ボイラープレートを減らせる (getter, equals, hashCode, toString) パターンの網羅性を担保、 defaultを省略できる

Slide 18

Slide 18 text

ؔ࿈ػೳͷ੝Γ߹Θͤ 18 String result = switch (action) { case null -> "No action provided"; case Click(int x, int y) when x > 0 && y > 0 -> "Clicked at positive coordinates"; case Click(int x, int y) -> "Clicked at " + x + ", " + y; case Drag(int startX, int startY, int endX, int endY) -> "Dragged from " + startX + " to " + endX; case Scroll(int amount) when amount > 0 -> "Scrolled down by " + amount; case Scroll(int amount) when amount < 0 -> "Scrolled up by " + amount; case Scroll _ -> "No scrolling"; }; ガードパターンで 条件を追加できる 無名パターンで 変数が不要な時は 省略できる モデルの構造を変えずに 機能追加がしやすい nullの判定も できる

Slide 19

Slide 19 text

ύλʔϯϚονؔ࿈ػೳͷมભ ϓϨϏϡʔ ਖ਼ࣜϦϦʔε 19 TXJUDIࣜ JOTUBODFPG ύλʔϯϚον Ϩίʔυ γʔϧΫϥε TXJUDI ύλʔϯϚον Ϩίʔυ ύλʔϯ ແ໊ม਺ ແ໊ύλʔϯ ϓϦϛςΟϒܕ ύλʔϯ

Slide 20

Slide 20 text

઴͘৽͘͠ೖΔ ػೳͷ࿩΁ 20

Slide 21

Slide 21 text

+BWBͰೖͬͨػೳ ϓϦϛςΟϒܕͰJOTUBODFPG΍TXJUDIΛ࢖ͬͨ ύλʔϯϚον͕Ͱ͖Δ 21

Slide 22

Slide 22 text

ϓϦϛςΟϒܕͷύλʔϯϚον 22 String result = switch (value) { case int i when i < 0 -> "Negative number: " + i; case 0 -> "Zero"; default -> "Positive number: " + value; }; return switch (year) { case int y when (y % 400 == 0) -> y + "೥͸Ӟ೥Ͱ͢"; case int y when (y % 100 == 0) -> y + "೥͸Ӟ೥Ͱ͸͋Γ·ͤΜ"; case int y when (y % 4 == 0) -> y + "೥͸Ӟ೥Ͱ͢"; };

Slide 23

Slide 23 text

কདྷɿؔ࿈͢Δ$BOEJEBUF +&1%FSJWFE3FDPSE$SFBUJPO 1SFWJFX ϑΟʔϧυΛมߋͯ͠ ϨίʔυΫϥεͷΠϯελϯεΛෳ੡Ͱ͖Δ 23

Slide 24

Slide 24 text

কདྷɿؔ࿈͢Δ$BOEJEBUF 24 record Point(int x, int y) { } Point oldLoc = new Point(1, 2); // x࠲ඪΛมߋͯ͠৽͍͠ϨίʔυΛ࡞੒ Point newLoc = oldLoc with { x = 0; }; // xͱy࠲ඪΛ2ഒʹͯ͠৽͍͠ϨίʔυΛ࡞੒ Point finalLoc = newLoc with { x *= 2; y *= 2; }; シンプルに書けるし Recordの イミュータブルな 特性をいかせる

Slide 25

Slide 25 text

͓͞Β͍ • ύλʔϯϚονΛ׆༻ͯ͠ϘΠϥʔϓϨʔτ͕ݮΒͤՄಡੑ͕ ্͕Δ • ݱঢ়+BWBͷύλʔϯϚονͰ͸JOTUBODFPG΍TXJUDIΛ׆༻͢Δ • ܕΛ࢖ͬͯ҆શͳίʔυΛॻ͖΍͘͢ͳΔ • Ωϟετͷϛε͕ݮΒͤͨΓ • γʔϧΫϥεͰ࿙Εෆ଍͕ग़དྷͨΓ • ܕΛ׆༻͢Δ্ͰϨίʔυ͸͔ܽͤͳ͍ 25

Slide 26

Slide 26 text

5IBOLZPV 26