ฉันมีคำถามง่ายๆ - เราควรใช้คีย์เวิร์ดใหม่เมื่อสร้างอ็อบเจกต์ใน Scala เมื่อใด เมื่อเราพยายามสร้างอินสแตนซ์วัตถุ Java เท่านั้นหรือไม่?
ฉันมีคำถามง่ายๆ - เราควรใช้คีย์เวิร์ดใหม่เมื่อสร้างอ็อบเจกต์ใน Scala เมื่อใด เมื่อเราพยายามสร้างอินสแตนซ์วัตถุ Java เท่านั้นหรือไม่?
คำตอบ:
ใช้new
คำสำคัญเมื่อคุณต้องการอ้างถึงclass
ตัวสร้างของตัวเอง:
class Foo { }
val f = new Foo
ละเว้นnew
หากคุณกำลังอ้างถึงapply
วิธีการของวัตถุที่แสดงร่วม:
class Foo { }
object Foo {
def apply() = new Foo
}
// Both of these are legal
val f = Foo()
val f2 = new Foo
หากคุณสร้างคลาสเคส:
case class Foo()
Scala แอบสร้างวัตถุคู่ใจให้คุณโดยเปลี่ยนเป็นสิ่งนี้:
class Foo { }
object Foo {
def apply() = new Foo
}
ดังนั้นคุณสามารถทำได้
f = Foo()
สุดท้ายโปรดทราบว่าไม่มีกฎใดที่บอกว่าapply
เมธอดที่แสดงร่วมจะต้องเป็นพร็อกซีสำหรับตัวสร้าง:
class Foo { }
object Foo {
def apply() = 7
}
// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7
และเนื่องจากคุณได้กล่าวถึงคลาส Java: ใช่ - คลาส Java ไม่ค่อยมีอ็อบเจ็กต์ร่วมกับapply
เมธอดดังนั้นคุณต้องใช้new
และคอนสตรัคเตอร์ของคลาสจริง
เมื่อเราพยายามสร้างอินสแตนซ์วัตถุ java เท่านั้นหรือไม่?
ไม่ใช่เลย. มีสองกรณีทั่วไปเมื่อคุณเลือกnew
ใน scala ด้วยอ็อบเจ็กต์ซิงเกิลตัน (ซึ่งมักใช้ในการจัดเก็บฟังก์ชันคงที่และเป็นโรงงานที่คล้ายกับสิ่งที่คุณอาจเห็นใน java):
scala> object LonelyGuy { def mood = "sad" }
defined module LonelyGuy
scala> LonelyGuy
res0: LonelyGuy.type = LonelyGuy$@3449a8
scala> LonelyGuy.mood
res4: java.lang.String = sad
ด้วยคลาสเคส (ที่จริงแล้วข้างล่างมี class + object = รูปแบบการแสดงร่วมเช่นมีคลาสและอ็อบเจ็กต์ที่มีชื่อเดียวกัน):
scala> case class Foo(bar: String)
defined class Foo
scala> Foo("baz")
res2: Foo = Foo(baz)
ดังนั้นเมื่อคุณทำงานกับคลาสง่ายๆกฎจะเหมือนกับ Java
scala> class Foo(val bar: String)
defined class Foo
scala> new Foo("baz")
res0: Foo = Foo@2ad6a0
// will be a error
scala> Foo("baz")
<console>:8: error: not found: value Foo
Foo("baz")
โบนัสมีคลาสที่ไม่ระบุตัวตนในสกาล่าซึ่งสามารถสร้างได้ดังนี้:
scala> new { val bar = "baz" }
res2: java.lang.Object{val bar: java.lang.String} = $anon$1@10ee5b8
scala> res2.bar
res3: java.lang.String = baz
เมื่อเราพยายามสร้างอินสแตนซ์วัตถุ Java เท่านั้นหรือไม่?
ด้วย Scala 3 (ซึ่งน่าจะออกกลางปี 2020 แปดปีต่อมา) อิงจาก Dotty : never
Scala 3 จะลดลง " new
" เช่นเดียวกับในชุดข้อความนี้
แอปพลิเคชันผู้สร้างอนุญาตให้ใช้ไวยากรณ์การเรียกฟังก์ชันอย่างง่ายเพื่อสร้างอินสแตนซ์ของคลาสแม้ว่าจะไม่มีการนำวิธีการใช้งานมาใช้ก็ตาม
ตัวอย่าง:
class StringBuilder(s: String) {
def this() = this(s)
}
StringBuilder("abc") // same as new StringBuilder("abc")
StringBuilder() // same as new StringBuilder()
แอปพลิเคชันผู้สร้างสรุปฟังก์ชันการทำงานที่มีให้สำหรับคลาสเคสเท่านั้น แต่กลไกการทำงานนี้แตกต่างกันเล็กน้อย
แทนที่จะเป็นวิธีการที่สร้างขึ้นโดยอัตโนมัติใช้เราเพิ่มการตีความที่เป็นไปได้ใหม่ ๆf(args)
ในการเรียกใช้ฟังก์ชัน