นี่คือประเด็นสำคัญจาก การเขียนโปรแกรมใน Scala รุ่นที่สองโดย Martin Odersky, Lex Spoon, Bill Venners ฉันต้องการจดบันทึกประเด็นสำคัญบางประการ อาจดูพังทลายและไม่สมเหตุสมผลหากคุณไม่ได้อ่านหนังสือ นี่เป็นการอ้างอิงส่วนบุคคล อย่าลังเลที่จะแก้ไขฉันหากฉันได้ตีความสิ่งผิดปกติในโพสต์นี้

บทที่ 8— ฟังก์ชั่นและการปิด

Scala มีหลายวิธีในการกำหนดฟังก์ชัน เช่น ฟังก์ชันที่เป็นสมาชิกของวัตถุ ฟังก์ชันที่ซ้อนกันภายในฟังก์ชัน ค่าลิเทอรัลของฟังก์ชัน และค่าของฟังก์ชัน

8.1 วิธีการ

  • วิธีที่พบบ่อยที่สุด — สมาชิกของวัตถุที่เรียกว่า วิธีการ:def ที่กำหนดให้เป็นสมาชิกของคลาส ลักษณะ หรือวัตถุเดี่ยวเรียกว่าวิธีการ

8.2 ฟังก์ชั่นท้องถิ่น

  • หลักการออกแบบที่สำคัญของรูปแบบการเขียนโปรแกรมเชิงฟังก์ชัน: โปรแกรมควรแบ่งออกเป็นฟังก์ชันเล็กๆ จำนวนมากซึ่งแต่ละฟังก์ชันทำงานที่กำหนดไว้อย่างดี ให้ความยืดหยุ่นในการสร้างระบบที่ซับซ้อนด้วย Building Block ขนาดเล็ก
  • ปัญหา: ฟังก์ชันตัวช่วยอาจทำให้เนมสเปซของโปรแกรมเสียหายวิธีแก้ไข:Scala นำเสนอแนวทางในการกำหนดฟังก์ชันภายในฟังก์ชันอื่น ๆ .
  • สิ่งเหล่านี้เรียกว่า ฟังก์ชันท้องถิ่น: def ที่กำหนดไว้ภายในบล็อก สิ่งเหล่านี้มองเห็นได้เฉพาะภายในบล็อกที่ปิดล้อมเท่านั้น
  • ฟังก์ชันภายในเครื่องสามารถเข้าถึงพารามิเตอร์ของฟังก์ชันปิดล้อมได้

8.3 ฟังก์ชั่นชั้นหนึ่ง

  • Scala มี ฟังก์ชันชั้นหนึ่ง:Scala รองรับฟังก์ชันชั้นหนึ่ง ซึ่งหมายความว่าคุณสามารถแสดงฟังก์ชันในรูปแบบลิเทอรัลของฟังก์ชันได้ เช่น (x: Int) =› x+1 และนั่น ฟังก์ชันสามารถแสดงด้วยวัตถุ ซึ่งเป็นค่าฟังก์ชัน
  • ลิเทอรัลของฟังก์ชันถูกคอมไพล์เป็นคลาสที่เมื่อสร้างอินสแตนซ์ ณ รันไทม์จะเป็นค่าฟังก์ชัน ดังนั้นความแตกต่างระหว่างค่าตามตัวอักษรของฟังก์ชันและค่าก็คือค่าตามตัวอักษรมีอยู่ในซอร์สโค้ด ในขณะที่ค่ามีอยู่เป็นวัตถุ ณ รันไทม์

  • ค่าฟังก์ชันสามารถเก็บไว้ในตัวแปรและสามารถเรียกใช้ได้โดยใช้ตามปกติ ()

8.4 รูปแบบย่อของตัวอักษรฟังก์ชัน

  • ทำให้ฟังก์ชันลิเทอรัลสั้นลง: ละเว้นประเภทพารามิเตอร์ สิ่งนี้เรียกว่า การพิมพ์เป้าหมาย

  • ประการที่สอง เว้นวงเล็บรอบประเภทพารามิเตอร์ที่มีการอนุมานประเภทไว้

8.5 ไวยากรณ์ตัวยึดตำแหน่ง

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

8.6 ฟังก์ชันที่ใช้บางส่วน

  • รายการพารามิเตอร์ทั้งหมดสามารถแทนที่ด้วยขีดล่างได้

  • val a หมายถึงออบเจ็กต์ค่าฟังก์ชันซึ่งสร้างขึ้นโดยอัตโนมัติโดยคอมไพเลอร์ Scala จากผลรวม _ ซึ่งเป็นนิพจน์ฟังก์ชันที่ใช้บางส่วน คลาสที่สร้างขึ้นมีวิธี Apply ที่รับ 3 อาร์กิวเมนต์
  • ชุดอาร์กิวเมนต์บางส่วนสามารถส่งผ่านไปยังฟังก์ชันบางส่วนได้ดังตัวอย่างด้านล่าง:

  • นิพจน์ฟังก์ชันที่ใช้บางส่วนโดยที่พารามิเตอร์ทั้งหมดถูกละไว้ สามารถแสดงให้กระชับยิ่งขึ้นได้โดยไม่ต้องใช้ _ someNumbers.foreach(println)อนุญาตเฉพาะในตำแหน่งที่จำเป็นต้องมีฟังก์ชันเท่านั้น

8.7 การปิดตัว

  • การปิด:วัตถุฟังก์ชันที่จับตัวแปรอิสระ และถูกกล่าวว่า "ปิด" เหนือตัวแปรที่มองเห็นได้ในขณะที่ถูกสร้างขึ้น
  • ฟังก์ชันลิเทอรัลที่ไม่มีตัวแปรอิสระ เช่น (x: Int) =› x + 1 เรียกว่าเทอมปิด แต่ฟังก์ชันลิเทอรัลใดๆ ที่มีตัวแปรอิสระ เช่น (x: Int) =› x + more ถือเป็นคำเปิด
  • การปิดของ Scala จะจับตัวแปรเอง ไม่ใช่ตัวแปรที่อ้างอิง

8.8 แบบฟอร์มเรียกฟังก์ชันพิเศษ

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

  • อาร์กิวเมนต์ที่มีชื่อ- ช่วยให้คุณสามารถส่งผ่านอาร์กิวเมนต์ไปยังฟังก์ชันในลำดับอื่นได้ ไวยากรณ์: ฟังก์ชั่น (paramName1 = ค่า, paramName2 = ค่า)
  • ค่าพารามิเตอร์เริ่มต้น-อาร์กิวเมนต์สำหรับพารามิเตอร์ดังกล่าวสามารถละเว้นจากการเรียกใช้ฟังก์ชันได้ และจะใช้ค่าเริ่มต้นที่สอดคล้องกัน

8.9 การเรียกซ้ำส่วนท้าย

  • Tail recursive-ฟังก์ชันที่เรียกตัวเองว่าเป็นเพียงการกระทำสุดท้ายเท่านั้น
  • การติดตามฟังก์ชันแบบเรียกซ้ำส่วนท้าย: การเรียกทั้งหมดจะดำเนินการในเฟรมเดียว คุณสามารถปิดการเพิ่มประสิทธิภาพการเรียกหางเมื่อดูการติดตามสแต็กได้โดยการส่งอาร์กิวเมนต์ต่อไปนี้: -g:notailcalls
  • ข้อจำกัดของการเรียกซ้ำส่วนท้าย:Scala สามารถปรับให้เหมาะสมเฉพาะการเรียกซ้ำโดยตรงกลับไปยังฟังก์ชันเดียวกันกับที่ทำการโทร
  • การเรียกซ้ำทางอ้อมไม่มีการเพิ่มประสิทธิภาพใดๆ

  • ไม่มีการเพิ่มประสิทธิภาพการเรียกหางหากการเรียกครั้งสุดท้ายไปที่ค่าฟังก์ชัน

บทสรุป

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

ก่อนหน้า:



ต่อไป: