Skip to content

Commit 780a350

Browse files
committed
Universal Apply Methodsを修正
1 parent 08a6e90 commit 780a350

File tree

2 files changed

+46
-39
lines changed

2 files changed

+46
-39
lines changed

docs/step02/01_Scala3で追加された地味に嬉しい系の機能追加.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,12 @@ https://dotty.epfl.ch/docs/reference/other-new-features/trait-parameters.html
7070

7171
https://dotty.epfl.ch/docs/reference/other-new-features/creator-applications.html
7272

73-
- 元々 `case class` はコンパニオンオブジェクトに `apply` メソッドが暗黙的に追加されるので、`new` を書く必要はないが、Scala3 ではこのスキームをすべての具象クラスに一般化した
74-
- `class``inline def apply` を書くと、コンパニオンオブジェクトに `apply` メソッドが暗黙的に追加される
73+
- 元々 `case class` はコンパニオンオブジェクトに `apply` メソッドが暗黙的に追加されるので、インスタンス生成時に `new` を書く必要はなかったが、Scala3 ではこのスキームをすべての具象クラスに一般化した
74+
- `class` を定義すると、コンパニオンオブジェクトに対して、コンストラクタに対応した `apply` メソッドが自動的に追加される(constructor proxy と呼ばれている)
75+
- その結果、`class` のインスタンス生成時でも `new` が不要になった
76+
- Javaのクラスも `new` を書かずにインスタンス生成できるようになった
7577
- `new` を省略することで実装の詳細が隠され、コードがより読みやすくなる
7678

77-
```
78-
[個人メモ]
79-
new の省略といえば、これまでもコンパニオンオブジェクトに apply を書けば case class じゃなくても省略することはできました。
80-
それに加え、ファクトリはコンパニオンオブジェクトで明示的に書きたいとも思うのですが、
81-
それを class に inline def apply を明示的に書くことによるメリットがどれくらいあるか、考えたいなと。
82-
```
83-
8479
## Parameter Untupling
8580

8681
https://dotty.epfl.ch/docs/reference/other-new-features/parameter-untupling.html

step02/src/main/scala/com/github/shinharad/gettingStartedWithScala3/UniversalApplyMethods.scala

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,58 @@ package com.github.shinharad.gettingStartedWithScala3
22
package universalApplyMethods
33

44
//---
5-
// 今までの定義では new を書く必要があった
5+
// インスタンス生成で new が不要になった
66

7-
class StringBuilder(s: String):
8-
def this() = this("")
7+
class StringBuilder1(s: String):
8+
def this() = this("")
99

1010
def no1(): Unit =
11-
val sb1 = new StringBuilder("abc")
12-
// val sb2 = StringBuilder("abc") // compile error
13-
val sb2 = new StringBuilder()
14-
// val sb2 = StringBuilder() // compile error
1511

16-
//---
17-
// inline def apply を定義すると、コンパニオンオブジェクトに apply メソッドが暗黙的に追加される
18-
// これは、constructor proxies と呼ばれてる
12+
// 今まではインスタンスの生成に new を書いていたが
13+
val sb1 = new StringBuilder1("abc")
14+
val sb2 = new StringBuilder1()
15+
16+
// Scala3 では、new が不要になった
17+
val sb3 = StringBuilder1("abc")
18+
val sb4 = StringBuilder1()
1919

20-
class StringBuilder2(s: String):
21-
def this() = this("")
22-
inline def apply(s: String): StringBuilder2 = new StringBuilder2(s)
23-
inline def apply(): StringBuilder2 = new StringBuilder2()
20+
/*
21+
これは、コンパニオンオブジェクトにこういうイメージの apply メソッドが自動的に追加されるため
22+
constructor proxies と呼ばれてる
23+
object StringBuilder1:
24+
inline def apply(s: String): StringBuilder = new StringBuilder(s)
25+
inline def apply(): StringBuilder = new StringBuilder()
26+
*/
27+
28+
//---
29+
// Javaのクラスも new が不要になった
2430

25-
// その結果、new を書かなくてもインスタンスが生成できるようになる
2631
def no2(): Unit =
27-
val sb1 = StringBuilder2("abc")
28-
val sb2 = StringBuilder2()
32+
val list1 = java.util.ArrayList[String]()
33+
val map1 = java.util.HashMap[String, String]()
34+
35+
// Scala2 ではこうだった
36+
val list2 = new java.util.ArrayList[String]()
37+
val map2 = new java.util.HashMap[String, String]()
2938

3039
//---
31-
// もしも、コンパニオンオブジェクトに apply が明示的に定義されていたら?
40+
// 既にコンパニオンオブジェクトに apply が実装されていた場合は、自動追加されない
3241

33-
// コンパニオンオブジェクトで既に apply が定義されてる場合は、暗黙的に追加されない
34-
class StringBuilder3(s: String):
35-
def this() = this("")
36-
inline def apply(s: String): StringBuilder3 = new StringBuilder3(s)
37-
inline def apply(): StringBuilder3 = new StringBuilder3()
42+
class C(name: String)
43+
object C
3844

39-
object StringBuilder3:
40-
// 暗黙的に追加されないので、
41-
// どちらか一方をコメントアウトするとコンパイルエラーになる
42-
def apply(s: String): StringBuilder3 = new StringBuilder3(s)
43-
def apply(): StringBuilder3 = new StringBuilder3()
45+
class D(name: String)
46+
object D:
47+
def apply(name: String, age: Int): D = new D(name)
4448

4549
def no3(): Unit =
46-
val sb1 = StringBuilder3("abc")
47-
val sb2 = StringBuilder3()
50+
51+
// コンパニオンオブジェクトが存在していても apply は自動的に追加される
52+
val c = C("abc")
53+
54+
// コンパニオンオブジェクトに apply が実装されていたら自動追加はされない
55+
56+
// 以下はコンパイルエラー
57+
// val d1 = D("abc")
58+
59+
val d2 = new D("abc")

0 commit comments

Comments
 (0)