ฉันมักจะลองทุกชุดจนกว่าจะรวบรวม ใครช่วยอธิบายได้ไหมว่าฉันควรใช้ที่ไหน
ฉันมักจะลองทุกชุดจนกว่าจะรวบรวม ใครช่วยอธิบายได้ไหมว่าฉันควรใช้ที่ไหน
คำตอบ:
ฉันจะไม่เห็นด้วยกับคำตอบของ Chris ในเรื่องเดียว เรียน, และมีการเรียน แต่จะไม่ปรากฏเป็นคลาสใน bytecode เนื่องจากข้อ จำกัด ภายในของ JVMAny
AnyRef
AnyVal
สิ่งนี้เกิดขึ้นจากข้อเท็จจริงที่ว่าไม่ใช่ทุกอย่างใน Java ที่เป็นวัตถุ นอกจากวัตถุแล้วยังมีวัตถุดึกดำบรรพ์ อ็อบเจ็กต์ทั้งหมดใน Java สืบเชื้อสายมาจากjava.lang.Object
แต่ดั้งเดิมถูกแยกออกจากกันและในปัจจุบัน*ไม่สามารถขยายได้โดยโปรแกรมเมอร์ โปรดทราบด้วยว่าสิ่งดั้งเดิมมี "ตัวดำเนินการ" ไม่ใช่วิธีการ
ในทางกลับกันใน Scala ทุกอย่างเป็นวัตถุวัตถุทั้งหมดเป็นของคลาสและโต้ตอบด้วยวิธีการ JVM bytecode ที่สร้างขึ้นไม่ได้สะท้อนถึงสิ่งนี้ แต่ก็ไม่ได้ทำให้น้อยลงเช่นเดียวกับที่ Java มี generics แม้ว่า bytecode จะไม่มีก็ตาม
ดังนั้นใน Scala วัตถุทั้งหมดจึงสืบเชื้อสายมาจากAny
และรวมถึงสิ่งที่ Java พิจารณาวัตถุและสิ่งที่ Java ถือว่าเป็นสิ่งดั้งเดิม ไม่มีสิ่งที่เทียบเท่าใน Java เนื่องจากไม่มีการรวมกันดังกล่าว
ทุกสิ่งที่ถือว่าเป็นของดั้งเดิมใน Java นั้นสืบเชื้อสายมาจากAnyVal
ใน Scala จนกระทั่ง Scala 2.10.0 AnyVal
ถูกปิดผนึกและโปรแกรมเมอร์ไม่สามารถขยายได้ มันน่าสนใจที่จะดูว่าจะเกิดอะไรขึ้นกับ Scala บน. Net เนื่องจากความสามารถในการทำงานร่วมกันเพียงอย่างเดียวเรียกร้องให้ Scala อย่างน้อยก็รู้จัก "primitives" ที่ผู้ใช้กำหนดเอง
นอกจากนี้การขยายAny
คือAnyRef
ซึ่งเทียบเท่ากับjava.lang.Object
(บน JVM ในอัตราใดก็ได้)
ขึ้นอยู่กับกาลา 2.9.x ผู้ใช้จะไม่สามารถขยายAny
หรือAnyVal
ไม่อ้างอิงพวกเขาจาก Java แต่มีอยู่ใช้งานอื่น ๆ ที่พวกเขาจะถูกนำไปใน Scala โดยเฉพาะพิมพ์ลายเซ็น:
def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)
ความหมายแต่ละอย่างควรชัดเจนจากลำดับชั้น อย่างไรก็ตามสิ่งที่ควรทราบคือf
และh
จะกล่องอัตโนมัติ แต่g
จะไม่ นั่นเป็นสิ่งที่ตรงกันข้ามกับสิ่งที่ Java ทำในสิ่งนั้นf
และh
ไม่สามารถระบุได้และg
(กำหนดด้วยjava.lang.Object
) จะทำให้เกิดการชกมวยอัตโนมัติ
เริ่มต้นด้วย Scala 2.10.0 ผู้ใช้สามารถขยายAnyVal
หรือAny
ด้วยความหมายต่อไปนี้:
หากคลาสขยายออกไปจะAnyVal
ไม่มีการสร้างอินสแตนซ์สำหรับมันบนฮีปภายใต้เงื่อนไขบางประการ ซึ่งหมายความว่าฟิลด์ของคลาสนี้ (บน 2.10.0 อนุญาตให้ใช้เพียงฟิลด์เดียว - ไม่ว่าจะยังคงเห็นการเปลี่ยนแปลงอยู่หรือไม่) จะยังคงอยู่บนสแต็กไม่ว่าจะเป็นแบบดั้งเดิมหรือการอ้างอิงถึงอ็อบเจ็กต์อื่น วิธีนี้ช่วยให้สามารถขยายวิธีการได้โดยไม่ต้องเสียค่าใช้จ่ายในการสร้างอินสแตนซ์
ถ้าเป็นลักษณะขยายAny
แล้วก็สามารถนำมาใช้กับทั้งการเรียนที่ขยายและการเรียนที่ขยายAnyRef
AnyVal
PS: ในมุมมองของฉันเอง Java มีแนวโน้มที่จะทำตาม C # ในการอนุญาตให้ใช้ primitives "struct" และอาจเป็นแบบ typedef เนื่องจากการขนานกันโดยไม่ต้องหันหน้าไปทางพวกเขานั้นพิสูจน์ได้ยากที่จะบรรลุด้วยประสิทธิภาพที่ดี
เห็นสิ่งนี้ไหม ข้อความของเพจมีข้อสังเกตเกี่ยวกับการทำงานร่วมกันของ Java http://www.scala-lang.org/node/128
Any
และAnyVal
ฉันเชื่อว่าเป็นส่วนหนึ่งของระบบประเภทสกาลาและไม่ใช่คลาสดังกล่าว (ในลักษณะเดียวกับที่Nothing
เป็นประเภทไม่ใช่คลาส) คุณไม่สามารถใช้อย่างชัดเจนจากภายในโค้ด Java
Howwever ใน Java / Scala interoperation เมธอดที่ยอมรับ Java Object
จะคาดหวัง scala Any
/ AnyRef
.
คุณกำลังพยายามทำอะไรอยู่?
AnyRef
เตือนฉันว่าสิ่งนี้ยังคงลึกลับสำหรับฉัน
AnyVal
ถูกกำหนดให้เป็นsealed trait AnyVal extends Any
ไฟล์. แต่ใน Scala 2.10 นี้มีการเปลี่ยนแปลงไปabstract class AnyVal extends Any with NotNull
และมันก็เป็นไปได้ที่จะขยายด้วยคุณลักษณะการเรียนค่าใหม่เช่น:AnyVal
class MyValue(val u: Int) extends AnyVal