เครื่องหมายสกาล่ามัด


12

เป็นไปได้ไหมที่จะเรียกใช้เมธอดโดยใช้รูปแบบ infix?

ตัวอย่างเช่นใน Haskell ฉันสามารถเขียนฟังก์ชันต่อไปนี้:

x `isAFactorOf` y = x % y == 0

แล้วใช้มันเช่น:

if 2 `isAFactorOf` 10 ...

ซึ่งในบางกรณีอนุญาตให้อ่านรหัสได้มาก มีอะไรคล้ายกับที่เป็นไปได้ใน Scala หรือไม่ ฉันค้นหาคำว่า "Scala infix notation" แต่คำนั้นดูเหมือนจะหมายถึงบางสิ่งที่แตกต่างใน Scala

คำตอบ:


15

เริ่มต้นด้วยรุ่น 2.10 Scala แนะนำคลาสโดยนัยเพื่อจัดการกับปัญหานี้อย่างแม่นยำ

สิ่งนี้จะทำการแปลงโดยปริยายบนประเภทที่กำหนดให้กับคลาสที่ถูกล้อมรอบซึ่งสามารถมีวิธีและค่าของคุณเอง

ในกรณีเฉพาะของคุณคุณจะใช้สิ่งนี้:

implicit class RichInt(x: Int) {
  def isAFactorOf(y: Int) = x % y == 0
}

2.isAFactorOf(10)
// or, without dot-syntax
2 isAFactorOf 10

RichInt(2)โปรดทราบว่าเมื่อรวบรวมนี้จะจบลงมวยค่าดิบของเราเป็น คุณสามารถแก้ไขได้ด้วยการประกาศ RichInt ของคุณเป็นคลาสย่อยของAnyVal:

implicit class RichInt(val x: Int) extends AnyVal { ... }

สิ่งนี้จะไม่ทำให้เกิดมวย แต่มันมีข้อ จำกัด มากกว่าคลาสทั่วไปโดยนัย มันสามารถเพียง แต่มีวิธีการไม่ได้ค่าหรือรัฐ


2
คุณควรพูดถึงว่าคลาส implicit ไม่สามารถอยู่ในระดับบนสุดดังนั้นคลาส implicit จะต้องถูกกำหนดแบบโลคัล
Carcigenicate

3

โดยพื้นฐานแล้วใน Scala คุณไม่สามารถเรียกใช้ฟังก์ชันในลักษณะมัดได้ แต่คุณสามารถกำหนดวิธีการในประเภทซึ่งอาร์กิวเมนต์ซ้ายสามารถแปลงเป็นแบบปริยายได้ ดังนั้นสำหรับตัวอย่างของคุณคุณสามารถกำหนดคลาสที่มีเมธอด isAFactorOf (การเป็น Int) และระบุว่า Int สามารถแปลงเป็นอินสแตนซ์ของคลาสนี้ได้โดยปริยาย

หากคุณดูคำตอบนี้https://stackoverflow.com/a/3119671สำหรับคำถามอื่นคุณจะเห็นไวยากรณ์ใน Scala ที่ทำงานได้อย่างเท่าเทียมกัน


implicit class RichInt(i: Int) { def square() = i * i }มันคุ้มค่าที่ชี้ให้เห็นว่าเวอร์ชันใหม่ของสกาล่ามีโครงสร้างอย่างชัดเจนสำหรับเรื่องนี้ซึ่งคำตอบที่เชื่อมโยงไม่ได้ที่อยู่:
KChaloux
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.