ฉันจะส่งตัวแปรใน Scala ได้อย่างไร


คำตอบ:


282

เทคนิคที่ต้องการคือการใช้การจับคู่รูปแบบ สิ่งนี้จะช่วยให้คุณสามารถจัดการกับกรณีและปัญหาที่เป็นปัญหาอย่างไม่เป็นไปตามประเภทที่กำหนด:

g match {
  case g2: Graphics2D => g2
  case _ => throw new ClassCastException
}

บล็อกนี้จำลองความหมายของasInstanceOf[Graphics2D]วิธี แต่มีความยืดหยุ่นมากขึ้น ตัวอย่างเช่นคุณสามารถระบุสาขาที่แตกต่างกันสำหรับประเภทต่างๆได้อย่างมีประสิทธิภาพดำเนินการปลดเปลื้องตามเงื่อนไขหลายอย่างในเวลาเดียวกัน สุดท้ายคุณไม่ได้จริงๆต้องโยนข้อยกเว้นในการจับทุกพื้นที่ที่คุณยังสามารถกลับnull(หรือโดยเฉพาะอย่างยิ่งNone) Graphics2Dหรือคุณอาจจะป้อนสาขาสำรองบางส่วนที่ทำงานได้โดยไม่ต้อง

ในระยะสั้นนี่เป็นวิธีที่จะไปจริงๆ มันมีขนาดใหญ่กว่า syntactically เล็กน้อยasInstanceOfแต่ความยืดหยุ่นที่เพิ่มเข้ามานั้นคุ้มค่ามาก


19
+1 เพราะน่าสนใจ แต่มีมากเกินไปสำหรับสถานการณ์นี้ ไม่ใช่เหรอ
Eugene Yokota

จะเกิดอะไรขึ้นถ้าฉันได้จับคู่รูปแบบแล้ว แต่สูญเสียการอ้างอิงถึงค่า casted: <code> การจับคู่ฐาน {case MyConcrete (value) => base.asInstanceOf [MyConcrete] .something (value)} </code> มีวิธีรับ ' ฐาน' หล่อเพื่อ MyConcrete แม้ว่าต้องการดึง 'ค่า' โดยการใช้ประโยชน์จาก 'โทร unapply' ดำเนินการโดย 'กรณี MyConcrete (ค่า)'?
ithkuil

4
ลองทำสิ่งนี้: base match { case base @ MyConcrete(value) => base.something(value) } เห็นได้ชัดว่าเงาbaseเป็นตัวเลือก คุณสามารถได้อย่างง่ายดายเพียงใช้ชื่อตัวแปรที่แตกต่างกัน
Daniel Spiewak

สิ่งที่ฉันไม่ได้คือคุณจะได้ผลลัพธ์ของการจับคู่รูปแบบนี้เป็นตัวแปรได้อย่างไร เช่นเดียวกับในจาวาถ้ามันเป็น String a = (String) b; สิ่งที่เทียบเท่าสกาล่าจะเป็นอย่างไร
James McMahon

@JamesMcMahonval gResult = g match { case g2: Graphics2D => g2 case _ => throw new ClassCastException }
Kevin Meredith

224
g.asInstanceOf[Graphics2D];

36
เมื่อฉันคุ้นเคยกับ Scala ฉันเรียนรู้ที่จะไม่ใช้asInstanceOfเนื่องจากมันเอาชนะจุดประสงค์ของการมีระบบสแตติกแบบคงที่
Eugene Yokota

26
น่าเสียดายนี่เป็นการดำเนินการทั่วไปเมื่อใช้ Swing สำหรับการวาดภาพแบบกำหนดเองคุณต้องแทนที่เมธอด 'public void paintComponent (Graphics g)' พารามิเตอร์กราฟิกเป็นอินสแตนซ์ Graphics2D จริง ๆ แต่จำเป็นต้องใช้เพี้ยน รูปแบบการจับคู่รูปแบบน่าจะละเอียดมากกว่าที่รับประกัน จำเอาไว้: Sedulously หลบหนี hyperverbosity obfuscatory และยืดยาว!
hohonuuli

7
@hohonuuli ฉันคิดว่านักแสดงนั้นใช้ได้ดีในกรณีเฉพาะนั้น แต่ถ้าคุณใช้scala-swingส่วนประกอบพารามิเตอร์ของ paintComponent นั้นก็คือ Graphics2D ดังนั้นจึงไม่จำเป็นต้องใช้การร่าย
Luigi Plinge

2
ทำไมมันนานขนาดนี้? เหตุใดจึงเป็น "asInstanceOf เมื่อเป็น" หรือ "asof" คำหลักหรือวิธีการได้หรือไม่หรือทำไมพวกเขาไม่ได้ใช้ C ++ และ Java ทางเป็นตัวเลือกเพราะนั่นเป็นวิธีการทั่วไปและไม่มีปัญหาใหญ่กับมัน
LEMUEL ADANE

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