การสอนสกาลา
สรุปบทช่วยสอน Scala
บทช่วยสอนสกาล่านี้ครอบคลุมทุกแง่มุมและหัวข้อของสกาล่า คุณจะได้เรียนรู้พื้นฐานทั้งหมดตั้งแต่เริ่มต้น เช่น สกาล่าคืออะไร, กระบวนการติดตั้งของสกาล่า, โปรแกรมสกาล่า, ฟังก์ชันสกาล่า, การประเมินแบบ Lazy, อินเทอร์เฟซประเภท, คลาสและอ็อบเจ็กต์, การสืบทอด, นามธรรม, Java และความแตกต่างของสกาลา ฯลฯ
สกาล่าคืออะไร?
สกาล่า เป็นภาษาโปรแกรมแบบพิมพ์ข้อมูลแบบคงที่ซึ่งรวมเอาการเขียนโปรแกรมเชิงฟังก์ชันและเชิงวัตถุเข้าด้วยกันเพื่อเพิ่มความสามารถในการปรับขนาดของแอปพลิเคชัน Scala ทำงานบนแพลตฟอร์ม JVM เป็นหลักและยังสามารถใช้เขียนซอฟต์แวร์สำหรับแพลตฟอร์มเนทีฟโดยใช้ Scala-Native และ Javaต้นฉบับ รันไทม์ผ่าน ScalaJs
Scala เป็นภาษาที่ปรับขนาดได้ซึ่งใช้ในการเขียนซอฟต์แวร์สำหรับหลายแพลตฟอร์ม จึงได้ชื่อว่า “สกาล่า” ภาษานี้มีวัตถุประสงค์เพื่อแก้ไขปัญหาของ Java ในขณะเดียวกันก็กระชับมากขึ้น ออกแบบโดย Martin Odersky และเปิดตัวในปี 2003
ทำไมต้องเรียนสกาล่า
ต่อไปนี้เป็นเหตุผลสำคัญในการเรียนรู้ภาษาการเขียนโปรแกรม Scala:
- Scala นั้นง่ายต่อการเรียนรู้สำหรับโปรแกรมเมอร์เชิงวัตถุ Java นักพัฒนา กำลังกลายเป็นหนึ่งในภาษายอดนิยมในช่วงไม่กี่ปีที่ผ่านมา
- Scala นำเสนอฟังก์ชันชั้นหนึ่งสำหรับผู้ใช้
- Scala สามารถดำเนินการได้ JVMจึงเป็นการปูทางไปสู่การทำงานร่วมกันกับภาษาอื่นๆ
- ได้รับการออกแบบมาสำหรับแอปพลิเคชันที่ขับเคลื่อนด้วยข้อความพร้อมกัน กระจาย และยืดหยุ่น เป็นหนึ่งในภาษาที่มีความต้องการมากที่สุดในทศวรรษนี้
- เป็นภาษาที่กระชับ ทรงพลัง และสามารถเติบโตได้อย่างรวดเร็วตามความต้องการของผู้ใช้
- มันเป็นแบบเชิงวัตถุและมีคุณสมบัติการเขียนโปรแกรมเชิงฟังก์ชันมากมายที่ให้ความยืดหยุ่นอย่างมากแก่นักพัฒนาในการเขียนโค้ดในแบบที่พวกเขาต้องการ
- สกาล่ามีเป็ดหลายประเภท
- มันมีสำเร็จรูปน้อยกว่าถ้าคุณมาจาก Java
- กรอบการทำงาน Lift and Play ที่เขียนด้วย Scala อยู่ในกราฟการเติบโต
วิธีการติดตั้งสกาล่า
ในการเริ่มเขียนโปรแกรม Scala คุณต้องติดตั้งมันบนคอมพิวเตอร์ของคุณ เพื่อที่จะทำสิ่งนี้ คุณจะต้องเข้าไปที่เว็บไซต์ของพวกเขา https://www.scala-lang.org/download/ เพื่อดาวน์โหลด Scala เวอร์ชันล่าสุด
เมื่อทำตามลิงก์แล้ว เราจะพบตัวเลือกสองทางในการติดตั้ง Scala บนเครื่องของเรา สำหรับบทช่วยสอน Scala นี้ เราจะดาวน์โหลด IntelliJ IDEA.
เมื่อคุณไปที่ลิงค์ดาวน์โหลด คุณจะพบ IntelliJ IDE สองเวอร์ชัน
สำหรับบทช่วยสอน Scala นี้ เราจะดาวน์โหลด Community Edition ซึ่งให้ใช้งานฟรีและมาพร้อมกับทุกสิ่งที่คุณต้องการในการเขียนโปรแกรม Scala
ขั้นตอน 1) เลือกรุ่นชุมชน
บนเพจ ให้คลิกบนดรอปดาวน์ใน Community Edition
มันแสดงตัวเลือกให้เราดาวน์โหลด IntelliJ IDE ร่วมกับ JBR ซึ่งมีการใช้งาน JDK (Java Development Kit) OpenJDK ซึ่ง Scala จำเป็นต้องคอมไพล์และรันโค้ด
ขั้นตอน 2) เรียกใช้การติดตั้ง
เมื่อคุณดาวน์โหลด IntelliJ แล้ว ให้ดับเบิลคลิกเพื่อเรียกใช้ตัวช่วยติดตั้งและทำตามกล่องโต้ตอบ
ขั้นตอน 3) เลือกสถานที่
เลือกตำแหน่งที่จะติดตั้ง IDE
หากคุณไม่ได้ดาวน์โหลดไฟล์ที่มี JDK เราจะยังได้รับแจ้งให้เลือกช่องกาเครื่องหมายเพื่อดาวน์โหลด
ขั้นตอน 4) คลิกถัดไป
ปล่อยให้ค่าเริ่มต้นอื่นๆ เหมือนเดิมแล้วคลิกถัดไป
ขั้นตอน 5) คลิกที่ไอคอนเริ่มต้น
เมื่อการติดตั้งเสร็จสิ้น ให้รัน IntelliJ IDE โดยคลิกที่ไอคอนเริ่มต้นในเมนูเริ่มต้นเหมือนแอปพลิเคชันทั่วไป
คุณยังต้องผ่านขั้นตอนเพิ่มเติมในการเพิ่มปลั๊กอิน Scala ให้กับ IntelliJ คุณทำได้โดยคลิกเมนูแบบเลื่อนลงในเมนูกำหนดค่าที่ด้านล่างขวาของหน้าจอและเลือกตัวเลือกปลั๊กอิน
บนแท็บ Marketplace การค้นหา Scala จะแสดงปลั๊กอินเป็นผลลัพธ์แรกภายใต้แท็ก Languages
ขั้นตอน 6) ติดตั้งปลั๊กอิน
คลิกติดตั้งซึ่งจะทำให้ปลั๊กอินเริ่มการดาวน์โหลด
ขั้นตอน 7) รีสตาร์ท IDE
หลังจากการดาวน์โหลดเสร็จสิ้น คุณจะได้รับแจ้งให้รีสตาร์ท IDE เพื่อให้ปลั๊กอินที่ติดตั้งสามารถเริ่มทำงานได้
หลังจากรีสตาร์ท คุณจะพบว่าตัวเองอยู่ในหน้าเดียวกับเมื่อก่อนเมื่อเราเรียกใช้ IDE แต่คราวนี้เราได้ติดตั้งปลั๊กอิน Scala แล้ว
โปรแกรมสกาล่าเฮลโลเวิลด์
ขั้นตอน 1) เลือกตัวเลือกสร้างโครงการ ซึ่งจะนำเราไปสู่หน้าเว็บที่เราสามารถเลือกประเภทของภาษาที่โครงการของเราจะใช้ได้
ขั้นตอน 2) เลือก Scala โดยเลือกช่องกาเครื่องหมาย Scala และคลิกถัดไป
ขั้นตอน 3) เลือกตำแหน่งที่จะบันทึกไฟล์โครงการของเราและตั้งชื่อโครงการของเรา
หากไม่มีไดเร็กทอรี IntelliJ จะแจ้งให้เราขออนุญาตเพื่อสร้างโฟลเดอร์ ยอมรับและคลิกเสร็จสิ้น คุณจะถูกนำไปที่โปรเจ็กต์ Scala ของคุณ ซึ่งปัจจุบันไม่มีโค้ด Scala เลย
การโหลดดัชนีบางส่วนจะใช้เวลาสักระยะ ดังนั้นอย่ากังวลหากคุณไม่สามารถดำเนินการใดๆ ได้ทันทีในขณะที่มีแถบความคืบหน้าที่ด้านล่างของ IDE ของคุณ นั่นหมายความว่า IDE ของคุณกำลังโหลดไฟล์บางไฟล์ที่จำเป็นในการเรียกใช้ Scala และ ความช่วยเหลือเกี่ยวกับการเติมข้อความอัตโนมัติ IDE
ขั้นตอน 4) ต่อไป เราจะคลิกที่แท็บโครงการทางด้านซ้ายของ IDE และขยายเพื่อให้เราดูเนื้อหาของโครงการของเราได้
ในขณะนี้ โปรเจ็กต์ว่างเปล่าและมีเพียงโฟลเดอร์ .idea และไฟล์ hello-world.iml ที่สร้างโดย IDE จุดสนใจของเราคือโฟลเดอร์ src Src คือที่ที่เราจัดเก็บซอร์สโค้ดสำหรับโครงการของเรา เป็นที่ที่เราจะสร้างไฟล์ Scala ไฟล์แรกของเรา
ขั้นตอน 5) คลิกขวาที่ src เพื่อเปิดเมนูเพื่อสร้างไฟล์ Scala ใหม่
จากนั้นเราจะตั้งชื่อไฟล์ ในบทช่วยสอน Scala นี้ เราจะใช้คำว่า hello จากนั้นเลือกจากเมนูแบบเลื่อนลงว่าจะใส่เนื้อหาใดเป็นเนื้อหาของไฟล์ Scala จากเมนูแบบเลื่อนลง เลือก “วัตถุ”
เมื่อเราทำเช่นนี้ เราจะมีไฟล์ Scala ที่มีวัตถุ Singleton ที่เราจะใช้รันโค้ดของเรา
ตอนนี้คุณมีไฟล์ Scala พร้อมวัตถุ Hello แล้ว คุณจะเขียนโปรแกรมแรกโดยขยายออบเจ็กต์ที่คุณสร้างขึ้นโดยใช้คีย์เวิร์ด App
การขยายอ็อบเจ็กต์ของเราด้วย App จะบอกคอมไพเลอร์ว่าโค้ดใดที่จะรันเมื่อเริ่มโปรแกรมของคุณ ทันทีหลังจากขยาย App ลูกศรสีเขียวจะปรากฏขึ้นทางด้านซ้าย แสดงว่าขณะนี้คุณสามารถรันโปรแกรมของคุณได้
ภายในออบเจ็กต์ Hello เราเขียนหนึ่งฟังก์ชัน println() ซึ่งใช้ในการพิมพ์ข้อความที่อยู่ภายในไปยังคอนโซล เราจะรันโค้ดของเราโดยคลิกที่ลูกศรสีเขียว
การคลิกที่ลูกศรจะแสดงตัวเลือก Run สวัสดี เมื่อคลิกแล้ว โค้ดของเราจะเริ่มคอมไพล์ และหลังจากนั้นไม่กี่วินาที เราจะเห็นผลลัพธ์ของโปรแกรมของเราที่พิมพ์จากคอนโซลที่ฝังอยู่ใน IntelliJ IDE
เอาล่ะ เราได้ติดตั้ง Scala และรันโปรแกรมแรกของเราสำเร็จแล้ว
คุณสามารถทำอะไรกับสกาล่าได้
- การพัฒนาเว็บไซต์ส่วนหน้าด้วย ScalaJS
- การพัฒนามือถือทั้งคู่ Android การพัฒนาและ IOS – ด้วย Scala Native
- ไลบรารีฝั่งเซิร์ฟเวอร์เช่น HTTP4S, Akka-Http, Play Framework
- อินเทอร์เน็ตของสิ่งต่าง ๆ ที่ใช้
- การพัฒนาเกม
- NLP – การประมวลผลภาษาธรรมชาติโดยใช้ชุดไลบรารี ScalaNLP
- ทดสอบเทคนิคการเขียนโปรแกรมขั้นสูง เช่น Functional Programming และ Object-Oriented Programming
- สร้างแอปพลิเคชันการสื่อสารที่ทำงานพร้อมกันสูงโดยใช้ไลบรารีสำหรับ JVM ที่ได้รับแรงบันดาลใจจาก Erlang
- ใช้สำหรับการเรียนรู้ของเครื่องโดยใช้ไลบรารีเช่น Figaro ที่ทำการเขียนโปรแกรมความน่าจะเป็นและ Apache Spark ที่
ฟังก์ชั่นนิรนาม
ภาษาสกาล่ามีฟังก์ชันที่ไม่ระบุชื่อซึ่งเรียกอีกอย่างว่า ตัวอักษรฟังก์ชัน- Scala เป็นภาษาที่ใช้งานได้มักจะหมายความว่านักพัฒนาจะแบ่งปัญหาใหญ่ออกเป็นงานเล็กๆ จำนวนมาก และสร้างฟังก์ชันมากมายเพื่อแก้ไขปัญหาเหล่านี้ เพื่อให้ง่ายต่อการสร้างฟังก์ชัน Scala มีฟังก์ชันเหล่านี้ที่สามารถทำได้ เกิดขึ้นโดยไม่มีชื่อ- เราสามารถกำหนดตัวแปรหรือคำจำกัดความ 'def' ได้โดยตรงดังแสดงในตัวอย่าง Scala ด้านล่าง:
val multiplyByTwo = (n:Int) => n * 2 def multiplyByThree = (n:Int) => n *3
จากนั้นเราสามารถใช้วิธีปกติที่เราใช้ฟังก์ชันโดยส่งพารามิเตอร์ไปให้พวกมันดังนี้
multiplyByTwo(3) //6 multiplyByThree(4) //12
วิธีการเหล่านี้มีประโยชน์เมื่อเราต้องการมีโค้ดที่สะอาดและกระชับ เราสามารถใช้ฟังก์ชันที่ไม่ระบุชื่อเมื่อกำหนดวิธีการที่มีขนาดไม่ใหญ่และไม่ต้องใช้โค้ดจำนวนมากในร่างกาย สิ่งเหล่านี้เรียบง่ายมากและไม่จำเป็นต้องมีพิธีการในการสร้าง
วิธีการเหล่านี้ไม่ได้จำกัดอยู่เพียงฟังก์ชันที่มีอาร์กิวเมนต์ และสามารถใช้เพื่อสร้างอินสแตนซ์ของวิธีการที่ไม่ต้องใช้อาร์กิวเมนต์ใดๆ
val sayHello = ()=>{ println("hello") }
ฟังก์ชันที่ไม่ระบุชื่อเหล่านี้ส่วนใหญ่จะใช้ในส่วนอื่นๆ ของโค้ดของเรา ซึ่งเราต้องสร้างฟังก์ชันด่วนขึ้นมา
อีกสาเหตุหนึ่งว่าทำไมฟังก์ชันเหล่านี้จึงถูกเรียกว่า ฟังก์ชันอินไลน์- การใช้ฟังก์ชันที่ไม่ระบุชื่อเป็นรูปแบบทั่วไปที่ใช้อย่างแพร่หลายในไลบรารีคอลเลกชันเพื่อดำเนินการอย่างรวดเร็วกับคอลเลกชัน
ตัวอย่างเช่น เรามีวิธีการกรองที่ใช้ฟังก์ชันอินไลน์/ฟังก์ชันที่ไม่ระบุชื่อเพื่อสร้างคอลเลกชันอื่นที่มีเฉพาะองค์ประกอบที่ตรงตามเกณฑ์ที่เรากำหนดในฟังก์ชันที่ไม่ระบุชื่อ
val myList = List(1,2,3,4,5,6,7) val myEvenList = myList.filter((n: Int) => n % 2 == 0) //List(2,4,6) val myOddList = myList.filter((n:Int) => n % 2 != 0) //List(1,3,5,7)
ต่อไปนี้วิธีที่เรามีเป็นฟังก์ชันที่ไม่ระบุตัวตนคือวิธีที่ตรวจสอบว่าค่าที่เราได้รับจากรายการเป็นเลขคี่และเป็นเลขคู่และส่งคืนไอเท็ม
//the one checking that the value is even (n: Int) => n % 2 == 0 //the one checking that the value is odd (n:Int) => n % 2 != 0
ใน Scala คุณสามารถใช้ไวด์การ์ดโดยที่ไม่ได้ตั้งชื่อพารามิเตอร์ของฟังก์ชันที่ไม่ระบุตัวตนได้ ตัวอย่างเช่น
var timesTwo = (_:Int)*2 timesTwo(5) //10
ในสถานการณ์นี้ เราไม่ได้ตั้งชื่อพารามิเตอร์ที่เราส่งผ่าน สิ่งเดียวที่เราใช้ขีดล่างเพื่อเป็นตัวแทน
การประเมินขี้เกียจ
ภาษาส่วนใหญ่จะประเมินตัวแปรและพารามิเตอร์ของฟังก์ชันตามลำดับตามลำดับ ใน Scala เรามีคีย์เวิร์ดชื่อlazy ซึ่งช่วยในการจัดการกับค่าที่เราไม่ต้องการให้ประเมินจนกว่าจะมีการอ้างอิง
ตัวแปรที่ทำเครื่องหมายว่าขี้เกียจจะไม่ได้รับการประเมินในตำแหน่งที่กำหนดไว้ ซึ่งโดยทั่วไปเรียกว่าการประเมินแบบกระตือรือร้น และจะได้รับการประเมินเฉพาะเมื่อมีการอ้างอิงถึงในบางตำแหน่งในภายหลังของโค้ดเท่านั้น
สิ่งนี้มีประโยชน์เมื่อประเมินค่าซึ่งอาจเป็นการคำนวณที่มีราคาแพง หากไม่ใช่กรณีที่จำเป็นต้องใช้ค่าเสมอไป เราก็สามารถช่วยตัวเองจากการรันการคำนวณที่มีราคาแพง ซึ่งอาจทำให้ซอฟต์แวร์ของเราช้าลงโดยการทำให้ตัวแปรของเราขี้เกียจ
lazy val myExpensiveValue = expensiveComputation def runMethod()={ if(settings == true){ use(myExpensiveValue) }else{ use(otherValue) } }
นี่ไม่ใช่กรณีการใช้งานเดียวสำหรับตัวแปร Lazy นอกจากนี้ยังช่วยจัดการกับปัญหาการพึ่งพาแบบวงกลมในโค้ดอีกด้วย
ในกรณีที่การตั้งค่าเป็นเท็จ เราอาจไม่จำเป็นต้องใช้ myExpensiveValue ซึ่งสามารถช่วยให้เราไม่ต้องคำนวณราคาแพง ซึ่งช่วยให้แน่ใจว่าผู้ใช้มีช่วงเวลาที่ดีในการใช้แอปพลิเคชันของเรา เนื่องจากความต้องการอื่นๆ ของพวกเขาสามารถคำนวณได้อย่างเหมาะสมโดยไม่ล้นหลาม แรม
ในกรณีที่การตั้งค่าเป็นเท็จ เราอาจไม่จำเป็นต้องใช้ myExpensiveValue ซึ่งสามารถช่วยให้เราไม่ต้องคำนวณราคาแพง ซึ่งช่วยให้แน่ใจว่าผู้ใช้มีช่วงเวลาที่ดีในการใช้แอปพลิเคชันของเรา เนื่องจากความต้องการอื่นๆ ของพวกเขาสามารถคำนวณได้อย่างเหมาะสมโดยไม่ล้นหลาม แรม
ความเกียจคร้านยังช่วยในเรื่องอาร์กิวเมนต์ของฟังก์ชัน โดยที่อาร์กิวเมนต์จะใช้เฉพาะเมื่อมีการอ้างอิงภายในฟังก์ชันเท่านั้น แนวคิดนี้เรียกว่าพารามิเตอร์การโทรตามชื่อ
def sometimesUsedString(someValue:String, defaultValue:=> String)={ if(someValue != null){ use(defaultValue) }else{ use(someValue) } }
ภาษาจำนวนมากใช้การประเมินอาร์กิวเมนต์แบบเรียกตามค่า พารามิเตอร์ที่ส่งผ่านแบบเรียกตามชื่อจะได้รับการประเมินเฉพาะเมื่อจำเป็นในเนื้อหาของฟังก์ชันเท่านั้น และจะไม่ได้รับการประเมินก่อนหน้านั้น เมื่อประเมินค่าแล้ว ค่าจะถูกเก็บไว้และสามารถนำกลับมาใช้ใหม่ได้ในภายหลังโดยไม่จำเป็นต้องประเมินซ้ำอีก แนวคิดนี้เรียกว่าการจดจำ
ประเภทการอนุมาน
ใน Scala คุณไม่จำเป็นต้องประกาศประเภทของตัวแปรทุกตัวที่คุณสร้าง เนื่องจากคอมไพเลอร์ Scala สามารถอนุมานประเภทตามการประเมินทางด้านขวามือได้ สิ่งนี้ช่วยให้โค้ดของคุณกระชับมากขึ้น โดยช่วยให้เราไม่ต้องเขียนแบบสำเร็จรูปโดยที่ประเภทที่คาดหวังชัดเจน
var first:String = "Hello, " var second:String = "World" var third = first + second //the compile infers that third is of type String
ลำดับที่สูงกว่าฟังก์ชัน
ฟังก์ชันลำดับที่สูงกว่าคือฟังก์ชันที่สามารถรับฟังก์ชันเป็นอาร์กิวเมนต์และสามารถส่งคืนฟังก์ชันเป็นชนิดส่งคืนได้ ใน Scala ฟังก์ชั่นถือเป็นพลเมืองชั้นหนึ่ง การใช้ฟังก์ชันเหล่านี้ในลักษณะนี้ช่วยให้เรามีความยืดหยุ่นอย่างมากในประเภทของโปรแกรมที่เราสามารถทำได้ เราสามารถสร้างฟังก์ชันแบบไดนามิกและฟีดฟังก์ชันการทำงานแบบไดนามิกไปยังฟังก์ชันอื่นๆ ได้
def doMathToInt(n:Int, myMathFunction:Int=>Int): Int ={ myMathFunction(n) }
ในฟังก์ชันข้างต้น เราจะส่ง int และฟังก์ชันที่รับ int แล้วส่งคืน int เราสามารถส่งผ่านฟังก์ชันใดๆ ของลายเซ็นนั้นได้ ตามลายเซ็น เราหมายถึงอินพุตและเอาต์พุตของฟังก์ชัน ลายเซ็นของ Int=>Int หมายความว่าฟังก์ชันรับ Int เป็นอินพุตและส่งกลับ Int เป็นเอาต์พุต
ลายเซ็นต์ของ ()=>Int หมายความว่าฟังก์ชันจะไม่ทำอะไรเลยในขณะที่เป็นอินพุต และส่งกลับ Int เป็นเอาต์พุต ตัวอย่างของฟังก์ชันเช่นนั้นคือฟังก์ชันที่สร้าง int แบบสุ่มให้เรา
def generateRandomInt()={ return scala.util.Random.nextInt() }
ฟังก์ชั่นด้านบนมีลายเซ็นต์ ()=>Int
เราสามารถมีฟังก์ชันที่มีลายเซ็นต์สกาล่า ()=>Unit ซึ่งหมายความว่าฟังก์ชันจะไม่รับสิ่งใดและไม่ส่งคืนประเภท ฟังก์ชันนี้อาจทำการคำนวณบางประเภทโดยเปลี่ยนบางสิ่งให้ทำบางอย่างที่กำหนดไว้ล่วงหน้า
อย่างไรก็ตาม ไม่สนับสนุนวิธีการประเภทนี้ เนื่องจากดูเหมือนว่าเป็นกล่องดำที่อาจส่งผลต่อระบบในรูปแบบที่ไม่ทราบสาเหตุได้ นอกจากนี้ยังทดสอบไม่ได้ด้วย การมีประเภทอินพุตและเอาต์พุตที่ชัดเจนช่วยให้เราสามารถสรุปได้ว่าฟังก์ชันของเราทำอะไร
ฟังก์ชันลำดับที่สูงกว่าสามารถส่งคืนฟังก์ชันได้เช่นกัน
ตัวอย่างเช่น เราสามารถสร้างวิธีการที่จะสร้างฟังก์ชันการจ่ายกำลัง เช่น รับตัวเลขแล้วจ่ายกำลังให้กับมัน
def powerByFunction(n:Int):Int=>Int = { return (x:Int)=> scala.math.pow(x,n).toInt }
ฟังก์ชั่นข้างต้นรับ int ประเภทการส่งคืนของเราเป็นฟังก์ชันนิรนามที่ใช้ Int x * เราใช้ int x เป็นอาร์กิวเมนต์สำหรับฟังก์ชันกำลัง
แกงกะหรี่
ใน Scala เราสามารถแปลงฟังก์ชันที่รับอาร์กิวเมนต์สองตัวเป็นฟังก์ชันที่รับอาร์กิวเมนต์ทีละตัว เมื่อเราส่งผ่านอาร์กิวเมนต์หนึ่ง เราจะนำไปใช้บางส่วนและจบลงด้วยฟังก์ชันที่รับหนึ่งอาร์กิวเมนต์เพื่อทำให้ฟังก์ชันสมบูรณ์ Currying ช่วยให้เราสามารถสร้างฟังก์ชันโดยการเพิ่มข้อโต้แย้งบางส่วน
สิ่งนี้มีประโยชน์สำหรับการสร้างฟังก์ชันแบบไดนามิกก่อนที่เราจะมีอาร์กิวเมนต์ครบชุด
def multiply two numbers(n:Int)(m:Int): Unit ={ return n * m }
หากเราจำเป็นต้องสร้างฟังก์ชันที่คูณด้วยจำนวนเฉพาะเจาะจง เราก็ไม่จำเป็นต้องสร้างวิธีการคูณแบบอื่น
เราสามารถเรียก .curried บนฟังก์ชันของเราด้านบนและรับฟังก์ชันที่รับหนึ่งอาร์กิวเมนต์ก่อนแล้วส่งคืนฟังก์ชันที่นำไปใช้บางส่วน
def multiplyTwoNumbers(n:Int)(m:Int): Unit ={ return n * m } var multiplyByFive = multiplyTwoNumbers(5) multiplyByFive(4) //returns 20
การจับคู่รูปแบบ
Scala มีกลไกในตัวอันทรงพลังที่ช่วยให้เราตรวจสอบว่าตัวแปรตรงกับเกณฑ์ที่กำหนดหรือไม่ เหมือนกับที่เราจะทำในคำสั่ง switch ใน Java หรือในชุดคำสั่ง if/else ภาษามีการจับคู่รูปแบบที่เราสามารถใช้เพื่อตรวจสอบว่าตัวแปรมีประเภทใดประเภทหนึ่งโดยเฉพาะหรือไม่ การจับคู่รูปแบบใน Scala มีประสิทธิภาพมากและสามารถใช้ทำลายโครงสร้างส่วนประกอบที่มีวิธีการเลิกใช้ เพื่อรับฟิลด์ที่เราสนใจโดยตรงจากตัวแปรที่เรากำลังจับคู่
การจับคู่รูปแบบของ Scala ยังให้ไวยากรณ์ที่น่าพอใจมากกว่าเมื่อเปรียบเทียบกับคำสั่ง switch
myItem match { case true => //do something case false => //do something else case _ => //if none of the above do this by default }
เราเปรียบเทียบตัวแปรของเรากับชุดตัวเลือก และเมื่อตัวแปรที่เราจับคู่ตรงกับเกณฑ์ นิพจน์ทางด้านขวามือของลูกศรอ้วน (=>) จะประเมินและส่งคืนตามผลลัพธ์ของการจับคู่
เราใช้ขีดล่างเพื่อตรวจจับกรณีที่ไม่ตรงกันในโค้ดของเรา มันสะท้อนพฤติกรรมของกรณีเริ่มต้นเมื่อจัดการกับคำสั่งสวิตช์
class Animal(var legs:Int,var sound:String) class Furniture(var legs:Int, var color:Int, var woodType:String) myItem match { case myItem:Animal => //do something case myItem:Furniture => //do something else case _ => //case we have a type we don't recognize do sth else }
ในโค้ดด้านบน คุณสามารถค้นหาประเภทของตัวแปร myItem และอิงตามสาขานั้นไปยังโค้ดเฉพาะบางส่วนได้
การจับคู่รูปแบบจะตรวจสอบว่าตัวแปรตรงกันหรือไม่
ขีดล่างทำงานเป็นตัวยึดตำแหน่งที่ตรงกับเงื่อนไขอื่นใดที่ไม่ตรงกับรายการอื่นในคำสั่ง case ข้างต้น เราใช้ตัวแปร myItem และเรียกวิธีการจับคู่
- เราตรวจสอบว่า myItem ใช้จริงหรือไม่ และทำตรรกะบางอย่างที่ด้านขวามือของลูกศรอ้วน “=>”
- เราใช้ขีดล่างเพื่อจับคู่กับสิ่งใดก็ตามที่ไม่ตรงกับคำสั่งกรณีใด ๆ ที่เรากำหนดไว้ในโค้ด
ด้วยคลาส Case เราสามารถไปต่อและทำลายโครงสร้างคลาสเพื่อรับฟิลด์ภายในวัตถุได้
ด้วยการใช้คีย์เวิร์ดที่ปิดผนึกเพื่อกำหนดคลาสของเรา เราจะได้รับประโยชน์จากการให้คอมไพเลอร์ตรวจสอบเคสที่เราพยายามจับคู่อย่างละเอียดถี่ถ้วน และเตือนเราหากเราลืมจัดการกับเคสใดเคสหนึ่งโดยเฉพาะ
ไม่เปลี่ยนรูป
คุณสามารถสร้างค่าที่ฟังก์ชันอื่นๆ ใน Scala ไม่สามารถเปลี่ยนแปลงได้โดยใช้คีย์เวิร์ด val นี่คือความสำเร็จใน Java โดยใช้คำสำคัญสุดท้าย ใน Scala เราดำเนินการดังกล่าวโดยใช้คีย์เวิร์ด val เมื่อสร้างตัวแปรแทนการใช้ var ซึ่งเป็นอีกทางเลือกหนึ่งที่เราจะใช้เพื่อสร้างตัวแปรที่ไม่แน่นอน
ตัวแปรที่กำหนดโดยใช้คีย์เวิร์ด val เป็นแบบอ่านอย่างเดียว ในขณะที่ตัวแปรที่กำหนดด้วย var สามารถอ่านและเปลี่ยนแปลงได้โดยฟังก์ชันอื่นหรือโดยผู้ใช้ในโค้ดตามอำเภอใจ
var changeableVariable = 8 changeableVariable =10 //the compiler doesn't complain, and the code compiles successfully println(changeableVariable) //10 val myNumber = 7 myNumber = 4 //if we try this the code won't compile
การพยายามกำหนดค่าให้กับ myNumber หลังจากที่เราได้ประกาศว่าเป็น val ทำให้เกิดข้อผิดพลาดในการคอมไพล์เวลาหรือ "การกำหนดใหม่ให้กับ val"
เหตุใดจึงใช้ความไม่เปลี่ยนรูป?
ความไม่เปลี่ยนรูปช่วยให้เราป้องกันไม่ให้โค้ดและโปรแกรมเมอร์คนอื่นๆ เปลี่ยนแปลงค่าของเราโดยไม่คาดคิด ซึ่งจะนำไปสู่ผลลัพธ์ที่ไม่คาดคิดหากพวกเขาตั้งใจจะใช้ค่าที่เราจัดเก็บไว้ พวกเขาสามารถคัดลอกค่านั้นแทนได้ ด้วยวิธีนี้ ข้อบกพร่องที่อาจเกิดจากนักแสดงหลายคนที่เปลี่ยนตัวแปรเดียวกันจะถูกป้องกัน
คลาสและวัตถุ
เราทุกคนรู้ดีว่าวัตถุคือสิ่งมีชีวิตในโลกแห่งความเป็นจริง และคลาสคือเทมเพลตที่กำหนดวัตถุ ชั้นเรียนมีทั้งสถานะและพฤติกรรม สถานะเป็นค่าหรือตัวแปร พฤติกรรมเป็นวิธีการใน Scala
ให้เราดูว่าคุณสามารถกำหนดคลาส สร้างอินสแตนซ์ และใช้งานโดยใช้ Scala ได้อย่างไร
ในที่นี้ คลาสที่เรียกว่า Triangle ซึ่งมีตัวแปรสองตัวและฟังก์ชันสองตัว คุณยังสามารถใช้พารามิเตอร์ l และ b โดยตรงเป็นฟิลด์ในโปรแกรมได้ คุณมีวัตถุที่มีวิธีการหลักและสร้างอินสแตนซ์ของคลาสด้วยสองค่า
ตัวอย่าง:
class Rectangle( l: Int, b: Int) { val length: Int = l val breadth: Int = b def getArea: Int = l * b override def toString = s"This is rectangle with length as $length and breadth as $breadth" } object RectObject { def main(args: Array[String]) { val rect = new Rectangle(4, 5) println(rect.toString) println(rect.getArea) } }
ฟิลด์และวิธีการทั้งหมดจะเป็นค่าเริ่มต้นสาธารณะใน Scala จำเป็นต้องใช้การแทนที่เนื่องจากมีการกำหนดวิธี toString สำหรับ Object ใน Scala
มรดก
Scala มีการสืบทอดหลายประเภท (เช่น แบบเดียว หลายระดับ หลายแบบ ลำดับชั้น ไฮบริด) ที่มีจุดร่วมมากมายกับรูปแบบดั้งเดิมที่พบใน Java- คุณสามารถสืบทอดได้ทั้งจากคลาสและคุณสมบัติ คุณสามารถสืบทอดสมาชิกของคลาสหนึ่งไปยังอีกคลาสหนึ่งได้โดยใช้คีย์เวิร์ด “extends” ช่วยให้สามารถนำกลับมาใช้ใหม่ได้
สามารถสืบทอดจากคลาสเดียวหรือหลายคลาสได้ นอกจากนี้ยังสามารถสืบทอดจากคลาสย่อยที่คลาสย่อยนั้นมีคลาสพิเศษของตัวเองได้ โดยสร้างลำดับชั้นของการสืบทอดในกระบวนการ
ในตัวอย่าง Scala ด้านล่าง คลาส Base คือ Circle และคลาสที่ได้รับคือ Sphere วงกลมมีค่าที่เรียกว่ารัศมี ซึ่งสืบทอดมาจากคลาสทรงกลม วิธีการ calcArea ถูกแทนที่โดยใช้การแทนที่คำหลัก
ตัวอย่าง:
class Circle { val radius = 5; def calcArea = { println(radius * radius ) } } class Sphere extends Circle{ override def calcArea = { println(radius * radius * radius ) } } object SphereObject{ def main(args : Array[String]){ new Sphere().calcArea } }
สิ่งที่เป็นนามธรรม
ใน Scala เราสามารถสร้างเมธอดนามธรรมและฟิลด์สมาชิกโดยใช้คลาสและลักษณะนามธรรม ภายในคลาสและลักษณะนามธรรม เราสามารถกำหนดฟิลด์นามธรรมได้โดยไม่จำเป็นต้องนำไปใช้
ตัวอย่าง:
trait MakesSound{ var nameOfSound:String def sound():String } abstract class HasLegs(var legs:Int){ val creatureName:String def printLegs():String={ return s"$creatureName has this number of legs: $legs" } }
ฟิลด์เหล่านี้ถูกนำไปใช้โดยคลาสที่ขยายคุณลักษณะหรือคลาสแบบนามธรรม คุณสามารถใช้คุณลักษณะเพื่อสร้างสัญญาว่าแอปพลิเคชันของเราควรทำอะไรได้บ้าง จากนั้นจึงนำวิธีการเหล่านั้นไปใช้ในภายหลัง
trait DatabaseService{ def addItemName(itemName:String) def removeItem(itemId:Int) def updateItem(itemId:Int, newItemName:String) }
ด้วยวิธีนี้ เราสามารถวางแผนว่าแอปพลิเคชันของเราจะมีลักษณะอย่างไรโดยไม่ต้องใช้วิธีการต่างๆ ซึ่งสามารถช่วยให้เราจินตนาการได้ว่าวิธีการต่างๆ จะมีลักษณะอย่างไร มันเป็นไปตามรูปแบบที่รู้ว่าเป็นการเขียนโปรแกรมไปยังนามธรรมไม่ใช่การใช้งานจริง
คลาสที่นำหน้าด้วยคีย์เวิร์ด abstract สามารถมีทั้งวิธีนามธรรมและไม่ใช่นามธรรม แต่ไม่รองรับการสืบทอดหลายรายการในคลาสนามธรรม ดังนั้น คุณสามารถขยายคลาสนามธรรมได้มากที่สุดเพียงคลาสเดียว
วัตถุซิงเกิลตัน
Singleton คือคลาสที่สร้างอินสแตนซ์เพียงครั้งเดียวในโปรแกรม มาจากรูปแบบการเขียนโปรแกรมยอดนิยมและมีประโยชน์ที่เรียกว่า "รูปแบบซิงเกิลตัน" มีประโยชน์ในการสร้างอินสแตนซ์ที่มีอายุการใช้งานยาวนาน และจะเข้าถึงได้ทั่วไปทั่วทั้งโปรแกรมของคุณซึ่งมีสถานะเป็นส่วนสำคัญในการประสานงานเหตุการณ์ต่างๆ ของระบบ การสร้างคลาสดังกล่าวใน Scala นั้นเป็นเรื่องง่าย เนื่องจาก Scala ให้วิธีการง่ายๆ ในการสร้างซิงเกิลตันโดยใช้คีย์เวิร์ด object
object UserProfile{ var userName="" var isLoggedIn:Boolean = false }
จากนั้นเราสามารถอ้างอิงวัตถุนี้ตลอดทั้งโปรแกรมของเราด้วยการรับประกันว่าทุกส่วนของโปรแกรมของเราจะเห็นข้อมูลเดียวกันเนื่องจากมีเพียงอินสแตนซ์เดียวเท่านั้น
def getLoggedInStatus():Boolean={ return UserProfile.isLoggedIn } def changeLoggedInStatus():Boolean={ UserProfile.isLoggedIn = !UserProfile.isLoggedIn return UserProfile.isLoggedIn }
แนวคิดของสมาชิกแบบคงที่ไม่มีอยู่ใน Scala นั่นคือเหตุผลที่คุณต้องใช้ออบเจ็กต์ซิงเกิลซึ่งทำหน้าที่เหมือนสมาชิกแบบคงที่ของคลาส
ชั้นเรียนโดยปริยาย
คลาสโดยปริยายคือฟังก์ชันใหม่ที่เพิ่มเข้ามาหลังจากเวอร์ชัน 2.1 โดยมีจุดประสงค์หลักเพื่อเพิ่มฟังก์ชันใหม่ให้กับคลาสปิด
คีย์เวิร์ดโดยนัยควรถูกกำหนดไว้ในคลาส วัตถุ หรือลักษณะ ตัวสร้างหลักของคลาสโดยนัยควรมีอาร์กิวเมนต์เดียวในรายการพารามิเตอร์แรก นอกจากนี้ยังอาจรวมรายการพารามิเตอร์โดยนัยเพิ่มเติมด้วย
ในตัวอย่าง Scala ด้านล่าง มีการเพิ่มฟังก์ชันใหม่เพื่อแทนที่สระของสตริงที่มี *
object StringUtil { implicit class StringEnhancer(str: String) { def replaceVowelWithStar: String = str.replaceAll("[aeiou]", "*") } }
คุณต้องนำเข้าในชั้นเรียนที่คุณใช้อยู่
import StringUtil.StringEnhancer object ImplicitEx extends App { val msg = "This is Guru99!" println(msg.replaceVowelWithStar) }
การเขียนโปรแกรมเชิงวัตถุ (OOP) กับการเขียนโปรแกรมเชิงฟังก์ชัน (FP)
ในการเขียนโปรแกรมแบบ OOP โปรแกรมจะถูกสร้างขึ้นโดยการจัดกลุ่มข้อมูลและฟังก์ชันที่ทำงานกับข้อมูลดังกล่าวเป็นหน่วยที่เชื่อมต่อกันอย่างแน่นหนา อ็อบเจ็กต์จะส่งข้อมูลไปยังฟิลด์และเมธอดที่ทำงานกับอ็อบเจ็กต์นั้น ในการเขียนโปรแกรมรูปแบบนี้ การแยกส่วนข้อมูลเป็นหลัก เนื่องจากเมธอดที่สร้างขึ้นมีไว้เพื่อทำงานกับข้อมูล
การเขียนโปรแกรมเชิงฟังก์ชันในทางกลับกัน จะแยกข้อมูลและฟังก์ชันที่ทำงานกับข้อมูลออกจากกัน ซึ่งทำให้ผู้พัฒนาสามารถปฏิบัติต่อฟังก์ชันต่างๆ เสมือนเป็นการแยกส่วนและเป็นแรงขับเคลื่อนเมื่อสร้างแบบจำลองโปรแกรม
Scala ช่วยให้การเขียนโปรแกรมเชิงฟังก์ชันเป็นไปได้ด้วยการใช้ฟังก์ชันเป็นพลเมืองชั้นหนึ่ง ซึ่งทำให้สามารถส่งฟังก์ชันเหล่านี้ในรูปแบบค่าไปยังฟังก์ชันอื่นและส่งคืนในรูปแบบค่าได้เช่นกัน การผสมผสานระหว่างสองแนวคิดนี้ทำให้ Scala เป็นตัวเลือกที่ยอดเยี่ยมในการสร้างซอฟต์แวร์ที่ซับซ้อนในอุตสาหกรรมต่างๆ เช่น Data Science
กรอบการทำงานที่สำคัญบน Scala
นี่คือกรอบการทำงานที่สำคัญบางประการของ Scala
- เล่น เป็นเฟรมเวิร์กแอปพลิเคชันเว็บแบบโอเพ่นซอร์สที่ใช้ สถาปัตยกรรม MVC- เปิดตัวในปี 2007 และปัจจุบันได้รับอนุญาตภายใต้ Apache กลายเป็นเฟรมเวิร์กที่ได้รับความนิยมมากที่สุดบน GitHub ในปี 2013 บริษัท เช่น LinkedIn, Walmart, Samsung, Eero ใช้เฟรมเวิร์กนี้
- ยก เป็นอีกหนึ่งเฟรมเวิร์กเว็บฟรีที่เขียนใน Scala เปิดตัวในปี 2007 Foursquare ใช้เฟรมเวิร์ก Lift มีประสิทธิภาพสูง รวดเร็วในการสร้างกรอบงาน
- อัคคะ
- แมว
- Spark
การสนับสนุนพร้อมกัน
- ค่าใน Scala นั้นเป็นค่าเริ่มต้นที่ไม่เปลี่ยนรูป ทำให้สามารถปรับตัวให้เข้ากับสภาพแวดล้อมที่เกิดขึ้นพร้อมกันได้อย่างมาก
- มีคุณสมบัติมากมายใน Scala ที่ทำให้ดีที่สุดสำหรับแอปพลิเคชันที่ทำงานพร้อมกัน
- สัญญาซื้อขายล่วงหน้าและสัญญาทำให้การประมวลผลข้อมูลแบบอะซิงโครนัสง่ายขึ้น จึงรองรับการทำงานแบบคู่ขนาน
- Akka – ชุดเครื่องมือที่ใช้โมเดลการทำงานพร้อมกันของนักแสดง มีนักแสดงจำนวนหนึ่งที่ทำหน้าที่เมื่อได้รับข้อความ
- เห็นพ้องต้องกันโดยใช้เธรดจาก Java ยังสามารถรองรับใน Scala ได้
- การประมวลผลสตรีมเป็นคุณสมบัติที่ยอดเยี่ยมอีกประการหนึ่งที่ช่วยให้สามารถประมวลผลข้อมูลแบบเรียลไทม์ได้อย่างต่อเนื่อง
Scala มีไลบรารีการทำงานพร้อมกันที่ดีที่สุดบางส่วนใน Java ระบบนิเวศ
- พื้นเมือง Java หัวข้อ
- ไฟเบอร์จากห้องสมุดเช่น Vertex
- ZIO – ไลบรารีที่มีฟังก์ชันพื้นฐานที่ช่วยให้เราจัดการกับการประมวลผลพร้อมกันและแบบอะซิงโครนัส
- STM – ธุรกรรม
- อนาคต - สร้างขึ้นในภาษาสกาล่า
Java ปะทะสกาล่า
นี่คือหลัก ความแตกต่างระหว่าง Java และสกาล่า.
สกาล่า | Java |
---|---|
กะทัดรัดและกระชับยิ่งขึ้น | โค้ดที่มีขนาดใหญ่กว่าเมื่อเปรียบเทียบกัน |
ออกแบบและพัฒนาให้เป็นทั้งภาษาเชิงวัตถุและเชิงฟังก์ชัน รองรับคุณสมบัติการเขียนโปรแกรมเชิงฟังก์ชันที่หลากหลาย เช่น การเห็นพร้อมกัน ความไม่เปลี่ยนรูป |
เดิมทีถูกพัฒนาให้เป็นภาษาเชิงวัตถุและเริ่มรองรับฟีเจอร์การเขียนโปรแกรมเชิงฟังก์ชันในช่วงไม่กี่วันที่ผ่านมา แต่ยังไม่แข็งแกร่งเท่าภาษาการเขียนโปรแกรมเชิงฟังก์ชัน |
ใช้ Actor Model เพื่อรองรับการทำงานพร้อมกันที่ทันสมัย | ใช้โมเดลแบบเกลียวทั่วไปเพื่อให้ทำงานพร้อมกันได้ |
รองรับเฟรมเวิร์ก – เล่น, ยก | รองรับ Spring, Grails และอื่นๆ อีกมากมาย |
รองรับการประเมินแบบขี้เกียจ | ไม่รองรับการประเมินแบบขี้เกียจ |
ไม่มีสมาชิกแบบคงที่ | ประกอบด้วยสมาชิกแบบสแตติก |
รองรับการโอเวอร์โหลดของผู้ปฏิบัติงาน | ไม่รองรับการโอเวอร์โหลดของตัวดำเนินการ |
การรวบรวมซอร์สโค้ดค่อนข้างช้า | การคอมไพล์ซอร์สโค้ดเร็วกว่า Scala |
ลักษณะนิสัย – ทำตัวเหมือน Java 8 อินเทอร์เฟซ | Java อินเทอร์เฟซ 8 รายการพยายามเชื่อมช่องว่างระหว่างคลาสและอินเทอร์เฟซ |
จำเป็นต้องเขียนใหม่ | ไม่จำเป็นต้องเขียนใหม่ |
ไม่มีการรับประกันเกี่ยวกับรหัสที่ปราศจากข้อผิดพลาด | รับประกันข้อบกพร่องที่น้อยกว่าอย่างสมบูรณ์ |
รองรับความเข้ากันได้แบบย้อนหลัง | Scala ไม่รองรับความเข้ากันได้แบบย้อนหลัง |
OperaTors ได้รับการปฏิบัติที่แตกต่างกันใน Java และไม่ใช่การเรียกเมธอด | ตัวดำเนินการทั้งหมดในรายการจะผ่านวิธีการที่เรียกว่าใน Scala |
รองรับการสืบทอดหลายรายการโดยใช้คลาส แต่ไม่ใช่โดยคลาสนามธรรม | ไม่รองรับการสืบทอดหลายรายการโดยใช้คลาส แต่โดยอินเทอร์เฟซ |
รหัสถูกเขียนในรูปแบบกะทัดรัด | โค้ดเขียนในรูปแบบยาว |
Scala ไม่มีคำหลักแบบคงที่ | Java มีคำหลักแบบคงที่ |
สรุป
ในบทช่วยสอนนี้ คุณได้เรียนรู้วิธีเริ่มต้นใช้งาน Scala แล้ว คุณยังได้เรียนรู้คุณสมบัติการทำงานและเชิงวัตถุด้วย คุณยังได้ค้นพบความเหมือนและความแตกต่างระหว่าง Java และสกาล่า บทช่วยสอนนี้น่าจะช่วยให้คุณมีตัวอย่างที่หลากหลายซึ่งแสดงให้เห็นได้ชัดเจน