ลักษณะที่ผนึกคืออะไร


332

คลาสที่ปิดผนึกมีการอธิบายไว้ใน 'การเขียนโปรแกรมใน Scala' แต่ลักษณะที่ซีลไม่ได้ ฉันจะหาข้อมูลเพิ่มเติมเกี่ยวกับลักษณะที่ผนึกได้จากที่ไหน

ฉันอยากจะรู้ว่าถ้าลักษณะที่ปิดผนึกเหมือนกันกับชั้นเรียนที่ปิดผนึกหรือไม่? หรือถ้าไม่อะไรคือความแตกต่าง? เมื่อไรจึงควรใช้ลักษณะที่ปิดสนิท (และเมื่อไม่)

คำตอบ:


472

sealedลักษณะสามารถขยายเฉพาะในไฟล์เช่นเดียวกับการประกาศ

พวกเขามักจะใช้เพื่อเป็นทางเลือกให้กับ enumsพวกเขามักจะใช้เพื่อให้ทางเลือกในการเนื่องจากสามารถขยายได้ในไฟล์เดียวเท่านั้นคอมไพเลอร์จึงทราบชนิดย่อยที่เป็นไปได้ทั้งหมดและสามารถให้เหตุผลได้

เช่นการประกาศ:

sealed trait Answer
case object Yes extends Answer
case object No extends Answer

คอมไพเลอร์จะส่งเสียงเตือนหากการแข่งขันไม่สมบูรณ์:

scala> val x: Answer = Yes
x: Answer = Yes

scala> x match {
     |   case No => println("No")
     | }
<console>:12: warning: match is not exhaustive!
missing combination            Yes

ดังนั้นคุณควรใช้ลักษณะที่ปิดผนึก (หรือคลาสนามธรรมปิดผนึก) หากจำนวนของชนิดย่อยที่เป็นไปได้นั้นมี จำกัด และเป็นที่รู้จักล่วงหน้า สำหรับตัวอย่างเพิ่มเติมคุณสามารถดูรายการและการใช้งานตัวเลือก


113
ฉันใช้เวลาหกเดือนในการมาถึงที่นี่แบบสุ่มและเข้าใจวิธีแทนที่ Java Enum ใน Scala
sscarduzio

1
ดีมาก ! และไม่เพียง แต่ จำกัด และรู้ล่วงหน้า แต่ยังเป็นส่วนหนึ่งของบริบทที่ถูก จำกัด (ปิดผนึก?) ที่เหมาะสมที่จะตรวจสอบชนิดย่อยที่เป็นไปได้ทั้งหมดเช่นใช่ | ไม่แม้แต่ | คี่ ฯลฯ ...
Mário de Sá Vera

90

ลักษณะที่ปิดผนึกเป็นเช่นเดียวกับชั้นเรียนที่ปิดผนึก?

เท่าที่sealedไปใช่ พวกเขาแบ่งปันความแตกต่างปกติระหว่างtraitและclassแน่นอน

หรือถ้าไม่อะไรคือความแตกต่าง?

ดำริ

เป็นความคิดที่ดีที่จะใช้คุณลักษณะที่ปิดสนิทเมื่อใด (และเมื่อใด)

หากคุณมี a sealed class Xคุณต้องตรวจสอบXเช่นเดียวกับคลาสย่อยใด ๆ เช่นเดียวกับที่ไม่เป็นความจริงของหรือsealed abstract class X sealed trait Xดังนั้นคุณสามารถทำได้sealed abstract class Xแต่นั่นเป็นวิธีที่ verbose มากกว่าเพียงแค่traitและเพื่อประโยชน์น้อย

ข้อได้เปรียบหลักของการใช้แบบabstract classover a traitก็คือสามารถรับพารามิเตอร์ได้ ข้อได้เปรียบนั้นมีความเกี่ยวข้องโดยเฉพาะอย่างยิ่งเมื่อใช้คลาสประเภท สมมติว่าคุณต้องการสร้างต้นไม้เรียงตัวอย่างเช่น คุณสามารถเขียนสิ่งนี้:

sealed abstract class Tree[T : Ordering]

แต่คุณไม่สามารถทำสิ่งนี้:

sealed trait Tree[T : Ordering]

เนื่องจากขอบเขตบริบท (และขอบเขตการดู) ถูกนำไปใช้พร้อมกับพารามิเตอร์โดยนัย เนื่องจากคุณลักษณะนั้นไม่สามารถรับพารามิเตอร์ได้คุณจึงไม่สามารถทำเช่นนั้นได้

ส่วนตัวผมชอบและใช้มันจนกว่าเหตุผลบางอย่างโดยเฉพาะอย่างยิ่งทำให้ฉันใช้sealed trait sealed abstract classและฉันไม่ได้พูดถึงเหตุผลที่ละเอียดอ่อน แต่เหตุผลในหน้าของคุณคุณไม่สามารถเพิกเฉยได้เช่นการใช้คลาสประเภท


"เนื่องจากขอบเขตบริบท (และขอบเขตการดู) ถูกนำไปใช้กับพารามิเตอร์ปริยาย" - คุณอธิบายรายละเอียดเกี่ยวกับเรื่องนั้นได้ไหม?
Ruby

@Ruby - การตอบกลับล่าช้า แต่ในกรณีที่คุณหรือคนอื่นสนใจ: การเชื่อมโยงบริบท ( [A: F]) ไม่ทำงานเช่นเดียวกับข้อ จำกัด ด้านผลต่าง แต่มันคือน้ำตาลซินแทคติคที่ต้องการF[A]ขอบเขตโดยนัย โดยทั่วไปแล้วจะใช้เพื่อเรียกใช้อินสแตนซ์ของคลาส typec ในลักษณะที่ค่อนข้างสั้นกว่าและอ่านง่ายกว่าพารามิเตอร์ปริยาย ( (implicit fa: F[A])) แต่ก็ยังใช้งานได้เหมือนเดิมภายใต้ประทุน ที่.
mirichan

54

จากบล็อกรายวัน - สกาล่า :

เมื่อคุณลักษณะเป็น "ปิดผนึก" คลาสย่อยทั้งหมดจะถูกประกาศภายในไฟล์เดียวกันและทำให้ชุดของคลาสย่อย จำกัด ซึ่งอนุญาตให้ตรวจสอบคอมไพเลอร์ได้


ขอบคุณ. ด้วย "subclasses ทั้งหมด" หมายความว่าคลาสและคุณสมบัติใช่หรือไม่
John Threepwood

@John - ฉันไม่ได้ลอง แต่ฉันสงสัยว่าเรียน ประเด็นเกี่ยวกับการปิดผนึกคือทุกอย่างถูกกำหนดไว้ภายในหน่วยต้นทางเดียวนั่น
Brian Agnew

1
@JohnThreepwood: คลาสลักษณะและวัตถุ เวลาส่วนใหญ่ในสกาล่าคำว่า "คลาส" ถูกใช้เพื่ออ้างถึงคลาสลักษณะและวัตถุ เฉพาะเมื่อพูดถึงความแตกต่างเฉพาะระหว่างพวกเขามันหมายถึงชั้นเรียนเท่านั้น SLS ใช้คำว่า "เทมเพลต" เพื่ออ้างถึงทั้งคลาสและลักษณะ แต่คำนั้นไม่ได้ใช้มากนอก SLS และไม่มีคำใดที่ครอบคลุมทั้งสามคลาสลักษณะและวัตถุทั้งหมด
Jörg W Mittag

30

นอกจากนี้ฉันรู้สึกต้องการชี้ให้คุณไปที่ข้อมูลจำเพาะ:

ปิดผนึกเอ้อ Fi Modi นำไปใช้ในชั้นเดอ nitions Fi ปิดผนึกระดับอาจจะไม่ได้รับการถ่ายทอดโดยตรงยกเว้นถ้าแม่แบบสืบทอดเป็นนิยามในแฟ้มแหล่งที่มาเช่นเดียวกับระดับสืบทอด อย่างไรก็ตามคลาสย่อยของคลาสที่ปิดผนึกสามารถสืบทอดได้ทุกที่

- M. Odersky ข้อมูลจำเพาะภาษา Scala เวอร์ชัน 2.8 ออนไลน์, ก.ย. , 2013


7

สั้น ๆ :

  • ลักษณะที่ปิดผนึกสามารถขยายได้ในไฟล์เดียวกันเท่านั้น
  • รายการสิ่งนี้ทำให้คอมไพเลอร์ทราบประเภทย่อยที่เป็นไปได้ทั้งหมดได้ง่าย
  • ใช้ลักษณะที่ปิดผนึกเมื่อจำนวนของชนิดย่อยที่เป็นไปได้มี จำกัด และทราบล่วงหน้า
  • วิธีการสร้างบางสิ่งบางอย่างเช่น enum ใน Java
  • ช่วยในการกำหนดประเภทข้อมูลเกี่ยวกับพีชคณิต (ADT)

และสำหรับรายละเอียดเพิ่มเติม ทุกอย่างเกี่ยวกับลักษณะที่ปิดผนึกใน Scala

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.