การสอนสกาลา
⚡ สรุปอย่างชาญฉลาด
คู่มือ Scala Tutorial แนะนำภาษาโปรแกรมแบบ statically typed ที่ทำงานบน JVM ซึ่งผสานรวมการเขียนโปรแกรมเชิงวัตถุและการเขียนโปรแกรมเชิงฟังก์ชันเข้าด้วยกัน คู่มือนี้ครอบคลุมการติดตั้ง ไวยากรณ์ คุณสมบัติหลัก และเฟรมเวิร์กต่างๆ ที่ทำให้ Scala เหมาะอย่างยิ่งสำหรับการสร้างแอปพลิเคชันสมัยใหม่ที่ทำงานพร้อมกันได้ ปรับขนาดได้ และกระชับ

สกาล่าคืออะไร?
สกาล่า Scala เป็นภาษาโปรแกรมแบบกำหนดประเภทข้อมูลแบบคงที่ (statically typed) ที่ผสมผสานการเขียนโปรแกรมเชิงวัตถุและการเขียนโปรแกรมเชิงฟังก์ชัน เพื่อเพิ่มความสามารถในการขยายขนาดของแอปพลิเคชัน Scala ทำงานบนแพลตฟอร์ม JVM เป็นหลัก และนักพัฒนาสามารถใช้มันเพื่อเขียนซอฟต์แวร์สำหรับแพลตฟอร์มเนทีฟผ่าน Scala-Native หรือสำหรับเบราว์เซอร์ผ่าน ScalaJs และไลบรารีอื่นๆ ได้ Javaต้นฉบับ รันไทม์
Scala เป็นภาษาโปรแกรมที่ปรับขนาดได้ ใช้ในการสร้างซอฟต์แวร์สำหรับหลายแพลตฟอร์ม ซึ่งเป็นที่มาของชื่อภาษานั่นเอง ภาษาดังกล่าวได้รับการออกแบบมาเพื่อแก้ปัญหาความซ้ำซ้อนหลายประการที่พบในภาษาโปรแกรมทั่วไป Java ในขณะเดียวกันก็ยังคงความกระชับ Martin Odersky เป็นผู้ออกแบบ Scala และเวอร์ชันแรกที่เผยแพร่สู่สาธารณะปรากฏขึ้นในปี 2004
ทำไมต้องเรียนสกาล่า
ต่อไปนี้คือเหตุผลหลักที่ควรเรียนรู้ภาษาโปรแกรม Scala:
- Scala เป็นภาษาที่เรียนรู้ได้ง่ายสำหรับโปรแกรมเมอร์ที่เชี่ยวชาญด้านการเขียนโปรแกรมเชิงวัตถุ และ Java ภาษาโปรแกรมนี้ถูกพัฒนาโดยนักพัฒนา และกลายเป็นหนึ่งในภาษาโปรแกรมยอดนิยมในช่วงไม่กี่ปีที่ผ่านมา
- Scala นำเสนอฟังก์ชันชั้นเยี่ยมสำหรับผู้ใช้
- Scala สามารถรันได้บน JVMซึ่งเป็นการปูทางไปสู่การทำงานร่วมกันกับภาษาอื่นๆ
- ภาษาโปรแกรมนี้ได้รับการออกแบบมาสำหรับแอปพลิเคชันที่ทำงานพร้อมกัน กระจาย และมีความยืดหยุ่นสูง โดยใช้การส่งข้อความเป็นหลัก ทำให้เป็นหนึ่งในภาษาโปรแกรมที่เป็นที่ต้องการมากที่สุดในทศวรรษนี้
- เป็นภาษาที่มีเนื้อหากระชับ ทรงพลัง และสามารถพัฒนาได้อย่างรวดเร็วตามความต้องการของผู้ใช้
- มันเป็นภาษาโปรแกรมเชิงวัตถุและมีคุณสมบัติของการเขียนโปรแกรมเชิงฟังก์ชันมากมาย ทำให้ผู้พัฒนาสามารถเขียนโค้ดได้อย่างยืดหยุ่น
- Scala นำเสนอ Duck Typing ผ่านประเภทโครงสร้าง
- มีเนื้อหาที่ซ้ำซ้อนน้อยกว่า Java.
- เฟรมเวิร์ก Lift และ Play ซึ่งเขียนด้วยภาษา Scala ยังคงพัฒนาและได้รับความนิยมเพิ่มขึ้นอย่างต่อเนื่อง
วิธีการติดตั้งสกาล่า
ในการเริ่มต้นเขียนโปรแกรม Scala คุณต้องติดตั้ง Scala บนคอมพิวเตอร์ของคุณก่อน สามารถทำได้โดยเข้าไปที่เว็บไซต์อย่างเป็นทางการที่ https://www.scala-lang.org/download/ เพื่อดาวน์โหลด Scala เวอร์ชันล่าสุด
เมื่อคลิกลิงก์ คุณจะพบกับสองตัวเลือกสำหรับการติดตั้ง Scala สำหรับบทเรียน Scala นี้ เราจะใช้ตัวเลือกแรก IntelliJ IDEAซึ่งให้การสนับสนุน Scala ที่ยอดเยี่ยมตั้งแต่เริ่มต้นใช้งาน
เมื่อคุณคลิกที่ลิงก์ดาวน์โหลด คุณจะพบ IntelliJ IDE สองเวอร์ชัน
สำหรับบทเรียน Scala นี้ เราจะดาวน์โหลด Community Edition ซึ่งเป็นเวอร์ชันฟรีและมีทุกอย่างที่คุณต้องการในการเขียนโปรแกรม Scala
ขั้นตอน 1) เลือก Community Edition
บนหน้าเว็บ ให้คลิกเมนูแบบเลื่อนลงที่ Community Edition
มีตัวเลือกให้ดาวน์โหลด IntelliJ IDE พร้อมกับ JBR ซึ่งมีการใช้งาน JDK อยู่ด้วย (Java ชุดพัฒนาซอฟต์แวร์ (Development Kit) เช่น OpenJDK ซึ่ง Scala ต้องการใช้ในการคอมไพล์และรันโค้ด
ขั้นตอน 2) เริ่มการติดตั้ง
เมื่อดาวน์โหลด IntelliJ เสร็จแล้ว ให้ดับเบิ้ลคลิกไฟล์ติดตั้งและทำตามขั้นตอนที่ปรากฏบนหน้าจอ
ขั้นตอน 3) เลือกสถานที่
เลือกตำแหน่งที่จะติดตั้ง IDE
หากคุณไม่ได้ดาวน์โหลดแพ็กเกจที่มี JDK มาด้วย โปรแกรมติดตั้งจะยังคงแจ้งให้คุณเพิ่ม JDK ผ่านช่องทำเครื่องหมายระหว่างการตั้งค่า
ขั้นตอน 4) คลิกถัดไป
ปล่อยค่าเริ่มต้นอื่นๆ ไว้ตามเดิม แล้วคลิกถัดไป
โปรแกรมสกาล่าเฮลโลเวิลด์
ขั้นตอน 5) คลิกไอคอนเริ่มต้นระบบ
เมื่อการติดตั้งเสร็จสมบูรณ์แล้ว ให้เรียกใช้ IntelliJ IDE โดยคลิกที่ไอคอนเริ่มต้นในเมนู Start เหมือนกับการใช้งานแอปพลิเคชันทั่วไป
คุณยังต้องเพิ่มปลั๊กอิน Scala ลงใน IntelliJ คลิกเมนูดรอปดาวน์ในเมนูการตั้งค่าที่ด้านล่างขวาของหน้าจอ แล้วเลือกตัวเลือก Plugins
ในแท็บ Marketplace ให้ค้นหา Scala ปลั๊กอินจะปรากฏเป็นผลลัพธ์แรกภายใต้แท็ก Languages
ขั้นตอน 6) ติดตั้งปลั๊กอิน
คลิก ติดตั้ง เพื่อเริ่มดาวน์โหลดปลั๊กอิน Scala
ขั้นตอน 7) รีสตาร์ท IDE
หลังจากดาวน์โหลดเสร็จสิ้น คุณจะได้รับแจ้งให้รีสตาร์ท IDE เพื่อให้ปลั๊กอินที่ติดตั้งเริ่มทำงานได้
หลังจากรีสตาร์ท คุณจะกลับมาที่หน้าเดิม แต่คราวนี้ปลั๊กอิน Scala ได้รับการติดตั้งและพร้อมใช้งานแล้ว
ขั้นตอน 8) เลือก "สร้างโครงการ" ซึ่งจะนำคุณไปยังหน้าที่คุณสามารถเลือกภาษาสำหรับโครงการได้
ขั้นตอน 9) เลือก Scala โดยติ๊กช่องทำเครื่องหมาย Scala แล้วคลิก ถัดไป
ขั้นตอน 10) เลือกตำแหน่งที่จะบันทึกไฟล์โปรเจ็กต์และตั้งชื่อโปรเจ็กต์
หากโฟลเดอร์ดังกล่าวไม่มีอยู่ IntelliJ จะขออนุญาตสร้างโฟลเดอร์ ยอมรับและคลิกเสร็จสิ้น จากนั้นคุณจะถูกนำไปยังโปรเจ็กต์ Scala ของคุณ ซึ่งขณะนี้ยังไม่มีโค้ด Scala ใดๆ อยู่
การโหลดดัชนีใช้เวลาสักครู่ ดังนั้นอย่ากังวลหากคุณไม่สามารถใช้งาน IDE ได้ในขณะที่แถบแสดงความคืบหน้าปรากฏอยู่ด้านล่าง IDE กำลังโหลดไฟล์ที่จำเป็นสำหรับการรัน Scala และแสดงฟังก์ชันการเติมข้อความอัตโนมัติ
ขั้นตอน 11) คลิกแท็บ Project ทางด้านซ้ายของ IDE แล้วขยายเพื่อดูเนื้อหาของโปรเจ็กต์
ในขั้นตอนนี้ โปรเจ็กต์ยังว่างเปล่าและมีเพียงโฟลเดอร์ .idea และไฟล์ hello-world.iml ที่สร้างโดย IDE เท่านั้น จุดที่น่าสนใจคือโฟลเดอร์ src ซึ่งเก็บซอร์สโค้ดของโปรเจ็กต์ นี่คือที่ที่คุณจะสร้างไฟล์ Scala ไฟล์แรกของคุณ
ขั้นตอน 12) คลิกขวาที่ src เพื่อเปิดเมนูและสร้างไฟล์ Scala ใหม่
เลือกชื่อสำหรับไฟล์ สำหรับบทเรียน Scala นี้ ให้ใช้ชื่อดังต่อไปนี้ สวัสดีจากนั้นเลือก Object จากเมนูแบบเลื่อนลงสำหรับประเภทเนื้อหาของไฟล์ Scala
เมื่อคุณทำเช่นนี้เสร็จแล้ว คุณจะได้ไฟล์ Scala ที่มีอ็อบเจ็กต์ซิงเกิลตันซึ่งคุณจะใช้ในการรันโค้ด
ตอนนี้คุณมีไฟล์ Scala ที่มีอ็อบเจ็กต์ Hello แล้ว ให้เขียนโปรแกรมแรกของคุณโดยการขยายอ็อบเจ็กต์ที่คุณสร้างขึ้นโดยใช้คีย์เวิร์ด App
การขยายอ็อบเจ็กต์ด้วย App จะบอกคอมไพเลอร์ว่าควรเรียกใช้โค้ดส่วนใดเมื่อโปรแกรมเริ่มต้น ทันทีหลังจากขยาย App แล้ว ลูกศรสีเขียวจะปรากฏขึ้นทางด้านซ้าย ซึ่งแสดงว่าโปรแกรมสามารถทำงานได้แล้ว
ภายในอ็อบเจ็กต์ Hello ให้เขียนฟังก์ชัน println() เพื่อแสดงข้อความออกทางคอนโซล จากนั้นเรียกใช้โปรแกรมโดยคลิกที่ลูกศรสีเขียว
การคลิกที่ลูกศรจะแสดงตัวเลือก Run Hello การเลือกตัวเลือกนี้จะทำการคอมไพล์โค้ด และหลังจากนั้นไม่กี่วินาที ผลลัพธ์ของโปรแกรมจะปรากฏในคอนโซลของ IntelliJ
ตอนนี้คุณได้ติดตั้ง Scala เรียบร้อยแล้ว และได้รันโปรแกรมแรกของคุณแล้ว
คุณสามารถทำอะไรกับสกาล่าได้
Scala ถูกนำไปใช้อย่างแพร่หลายในหลายสาขาเนื่องจากมีความยืดหยุ่นและสามารถทำงานร่วมกับ JVM ได้ ตัวอย่างการใช้งานทั่วไป ได้แก่:
- การพัฒนาเว็บฝั่ง Frontend ด้วย ScalaJS
- การพัฒนาแอปพลิเคชันบนมือถือสำหรับ Android และ iOS ด้วย Scala Native
- ไลบรารีฝั่งเซิร์ฟเวอร์ เช่น HTTP4S, Akka-Http และ Play Framework
- แอปพลิเคชันอินเทอร์เน็ตของสรรพสิ่ง (IoT)
- การพัฒนาเกม
- การประมวลผลภาษาธรรมชาติโดยใช้ชุดไลบรารี ScalaNLP
- ฝึกฝนเทคนิคขั้นสูง เช่น การเขียนโปรแกรมเชิงฟังก์ชันและการเขียนโปรแกรมเชิงวัตถุไปพร้อมกัน
- แอปพลิเคชันการสื่อสารแบบขนานสูงโดยใช้ Actor ซึ่งเป็นไลบรารีสำหรับ JVM ที่ได้รับแรงบันดาลใจจาก Erlang
- การเรียนรู้ของเครื่องด้วยไลบรารีต่างๆ เช่น Figaro สำหรับการเขียนโปรแกรมเชิงความน่าจะเป็น และ Apache Spark สำหรับการประมวลผลข้อมูลขนาดใหญ่
ฟังก์ชั่นนิรนาม
ภาษา Scala รองรับฟังก์ชันนิรนาม หรือที่เรียกว่า ฟังก์ชันนิรนาม ตัวอักษรฟังก์ชันเนื่องจาก 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") }
ฟังก์ชันนิรนามส่วนใหญ่เหล่านี้ถูกใช้ในส่วนอื่นๆ ของโค้ดเมื่อต้องการฟังก์ชันอย่างเร่งด่วน ด้วยเหตุนี้จึงเรียกฟังก์ชันเหล่านี้ว่า ฟังก์ชันนิรนาม ฟังก์ชันอินไลน์การใช้ฟังก์ชันนิรนามเป็นรูปแบบทั่วไปที่พบได้ในไลบรารีคอลเลกชัน เพื่อดำเนินการต่างๆ กับคอลเลกชันอย่างรวดเร็ว
ตัวอย่างเช่น เมธอด filter จะรับฟังก์ชันแบบอินไลน์เพื่อสร้างคอลเลกชันใหม่ที่มีเฉพาะองค์ประกอบที่ตรงตามเกณฑ์ที่กำหนดไว้ในฟังก์ชันนิรนามเท่านั้น
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 ยังสามารถใช้สัญลักษณ์ตัวแทน (wildcards) ในกรณีที่พารามิเตอร์ของฟังก์ชันนิรนามไม่ได้ระบุชื่อได้อีกด้วย ตัวอย่างเช่น:
var timesTwo = (_:Int) * 2 timesTwo(5) //10
ในกรณีนี้ คุณไม่ต้องตั้งชื่อพารามิเตอร์ เครื่องหมายขีดล่างจะใช้แทนพารามิเตอร์นั้น
การประเมินขี้เกียจ
ภาษาโปรแกรมส่วนใหญ่จะประเมินค่าตัวแปรและพารามิเตอร์ของฟังก์ชันตามลำดับทีละตัว ในภาษา Scala คำหลักคือ `true` lazy ช่วยจัดการกับค่าต่างๆ ที่คุณไม่ต้องการประเมินจนกว่าจะมีการอ้างอิงถึง
ตัวแปรที่ถูกกำหนดให้เป็น lazy จะไม่ถูกประเมินค่า ณ จุดที่กำหนดค่า ซึ่งโดยทั่วไปเรียกว่าการประเมินค่าแบบ eager ตัวแปรจะถูกประเมินค่าก็ต่อเมื่อมีการอ้างอิงถึงในภายหลังในโค้ดเท่านั้น
วิธีนี้มีประโยชน์เมื่อการประเมินค่าใดค่าหนึ่งต้องใช้การคำนวณที่ซับซ้อน หากไม่จำเป็นต้องใช้ค่าดังกล่าวเสมอไป คุณก็ประหยัดเวลาในการคำนวณที่ซับซ้อนซึ่งอาจทำให้ซอฟต์แวร์ทำงานช้าลงได้ โดยการทำให้ตัวแปรเป็นแบบ lazy loading
lazy val myExpensiveValue = expensiveComputation def runMethod() = { if(settings == true) { use(myExpensiveValue) } else { use(otherValue) } }
นี่ไม่ใช่เพียงกรณีการใช้งานเดียวของตัวแปรแบบเลซี่ พวกมันยังช่วยจัดการกับความสัมพันธ์แบบวนซ้ำในโค้ดได้อีกด้วย
หากตั้งค่าแฟล็กเป็น false คุณไม่จำเป็นต้องใช้ myExpensiveValue ซึ่งจะช่วยประหยัดการคำนวณที่สิ้นเปลือง ทำให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ราบรื่น เนื่องจากไม่สิ้นเปลืองทรัพยากรไปกับค่าที่ไม่เคยถูกอ่าน
ความเกียจคร้านยังช่วยในเรื่องการใช้พารามิเตอร์ของฟังก์ชันด้วย โดยพารามิเตอร์เหล่านั้นจะถูกใช้ก็ต่อเมื่อมีการอ้างอิงถึงภายในฟังก์ชันเท่านั้น แนวคิดนี้เรียกว่า พารามิเตอร์แบบเรียกใช้ตามชื่อ (Call-by-name parameters)
def sometimesUsedString(someValue:String, defaultValue: => String) = { if(someValue != null) { use(defaultValue) } else { use(someValue) } }
ภาษาโปรแกรมหลายภาษาใช้วิธีการส่งค่าแบบ call-by-value ในการประเมินค่าอาร์กิวเมนต์ พารามิเตอร์ที่ส่งผ่านแบบ call-by-name จะถูกประเมินค่าก็ต่อเมื่อจำเป็นภายในตัวฟังก์ชันเท่านั้น เมื่อประเมินค่าแล้ว ค่าดังกล่าวจะถูกจัดเก็บไว้และสามารถนำกลับมาใช้ใหม่ได้ในภายหลังโดยไม่ต้องประเมินค่าซ้ำ ซึ่งเป็นแนวคิดที่เรียกว่า memoization
ประเภทการอนุมาน
ใน Scala คุณไม่จำเป็นต้องประกาศชนิดข้อมูลสำหรับตัวแปรทุกตัวที่คุณสร้าง เพราะคอมไพเลอร์ของ Scala สามารถอนุมานชนิดข้อมูลได้จากด้านขวาของนิพจน์ วิธีนี้ช่วยให้โค้ดของคุณกระชับขึ้นและช่วยให้คุณไม่ต้องเขียนโค้ดซ้ำซ้อนในจุดที่ชนิดข้อมูลที่คาดหวังนั้นชัดเจนอยู่แล้ว
var first:String = "Hello, " var second:String = "World" var third = first + second //the compiler infers that third is of type String
ฟังก์ชันลำดับสูงกว่า
ฟังก์ชันลำดับสูง (Higher-order function) คือฟังก์ชันที่สามารถรับฟังก์ชันอื่นเป็นอาร์กิวเมนต์ และส่งคืนค่าเป็นฟังก์ชันได้ ใน Scala ฟังก์ชันถือเป็นองค์ประกอบสำคัญ (first-class citizens) การใช้ฟังก์ชันในลักษณะนี้ทำให้คุณมีความยืดหยุ่นสูงในการสร้างโปรแกรม คุณสามารถสร้างฟังก์ชันแบบไดนามิกและส่งฟังก์ชันการทำงานไปยังฟังก์ชันอื่น ๆ แบบไดนามิกได้
def doMathToInt(n:Int, myMathFunction:Int=>Int): Int = { myMathFunction(n) }
ในฟังก์ชันด้านบน คุณส่งค่าเข้าไป 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 และใช้เป็นอาร์กิวเมนต์สำหรับฟังก์ชันกำลัง
แกงกะหรี่
ใน Scala คุณสามารถแปลงฟังก์ชันที่รับอาร์กิวเมนต์สองตัวให้เป็นฟังก์ชันที่รับอาร์กิวเมนต์ทีละตัวได้ เมื่อคุณส่งอาร์กิวเมนต์เข้าไปหนึ่งตัว คุณจะทำการประมวลผลเพียงบางส่วน และจะได้ฟังก์ชันที่รับอาร์กิวเมนต์ที่เหลือเพื่อทำการเรียกใช้ให้เสร็จสมบูรณ์ เทคนิค Currying ช่วยให้คุณสร้างฟังก์ชันโดยการเพิ่มอาร์กิวเมนต์บางส่วนเข้าไป
วิธีนี้มีประโยชน์สำหรับการสร้างฟังก์ชันแบบไดนามิกก่อนที่คุณจะมีชุดอาร์กิวเมนต์ครบถ้วน
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m }
หากคุณต้องการฟังก์ชันที่คูณด้วยตัวเลขเฉพาะ คุณไม่จำเป็นต้องสร้างวิธีการคูณใหม่ คุณสามารถใช้พารามิเตอร์เพียงตัวเดียวในฟังก์ชัน curried และนำผลลัพธ์มาใช้ซ้ำได้:
def multiplyTwoNumbers(n:Int)(m:Int): Int = { return n * m } var multiplyByFive = multiplyTwoNumbers(5) _ multiplyByFive(4) //returns 20
การจับคู่รูปแบบ
Scala มีกลไกที่มีประสิทธิภาพในตัวที่ช่วยให้คุณตรวจสอบว่าตัวแปรตรงตามเกณฑ์ที่กำหนดหรือไม่ คล้ายกับคำสั่ง switch ในภาษาโปรแกรม Java หรือชุดคำสั่ง if/else ภาษา Scala รองรับการจับคู่รูปแบบ (pattern matching) ซึ่งคุณสามารถใช้ตรวจสอบว่าตัวแปรนั้นมีประเภทใดประเภทหนึ่งหรือไม่ การจับคู่รูปแบบใน Scala นั้นทรงพลังและสามารถแยกส่วนประกอบที่มีรูปแบบเฉพาะได้ unapply วิธีการดึงข้อมูลฟิลด์ที่คุณสนใจโดยตรงจากตัวแปรที่กำลังจับคู่
การจับคู่รูปแบบใน Scala ยังมีไวยากรณ์ที่น่าใช้กว่าคำสั่ง switch อีกด้วย
myItem match { case true => //do something case false => //do something else case _ => //if none of the above do this by default }
คุณเปรียบเทียบตัวแปรกับชุดตัวเลือก เมื่อตัวแปรตรงตามเงื่อนไข นิพจน์ทางด้านขวาของเครื่องหมายลูกศรหนา (=>) จะถูกประเมินและส่งคืนผลลัพธ์ของการจับคู่
เครื่องหมายขีดล่าง (_) จะดักจับกรณีที่ไม่ตรงกับเงื่อนไขในโค้ด โดยเลียนแบบพฤติกรรมของกรณีเริ่มต้น (default case) ในคำสั่ง switch
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 _ => //unknown type, do something else }
ในโค้ดด้านบน คุณสามารถตรวจจับประเภทของได้ myItem ตัวแปร และจากนั้นจึงแยกย่อยไปยังโค้ดเฉพาะ
การตรวจสอบรูปแบบจะตรวจสอบว่าตัวแปรตรงกับแต่ละกรณีตามลำดับหรือไม่
เครื่องหมายขีดล่างทำหน้าที่เป็นตัวแทนที่ตรงกับเงื่อนไขใดๆ ที่คำสั่ง case อื่นๆ ไม่ตรงกัน คุณใช้ตัวแปร myItem และเรียก match วิธี
- ตรวจสอบว่า
myItemistrueและใช้ตรรกะทางด้านขวาของเครื่องหมายลูกศรหนา “=>” - ใช้เครื่องหมายขีดล่าง (_) เพื่อจับคู่กับสิ่งใดก็ตามที่ไม่ตรงกับเงื่อนไขใดๆ ที่กำหนดไว้ในโค้ด
ด้วยคลาสเคส คุณสามารถแยกโครงสร้างคลาสเพื่อยกตัวอย่างได้tracฟิลด์ t ภายในอ็อบเจ็กต์
โดยใช้ sealed การใช้คีย์เวิร์ดเพื่อกำหนดคลาส จะช่วยให้คุณได้รับประโยชน์จากการที่คอมไพเลอร์ตรวจสอบกรณีที่คุณพยายามจับคู่แบบครบถ้วน และจะแจ้งเตือนคุณหากคุณลืมจัดการกรณีใดกรณีหนึ่ง
ไม่เปลี่ยนรูป
เป็นไปได้ที่จะสร้างค่าที่ไม่สามารถเปลี่ยนแปลงได้ด้วยฟังก์ชันอื่นใน Scala โดยใช้... val คำหลัก สิ่งนี้สำเร็จได้ใน Java โดยใช้ final คำหลัก ใน Scala คุณใช้ a val เมื่อสร้างตัวแปรแทนที่จะ varซึ่งเป็นทางเลือกแทนตัวแปรที่เปลี่ยนแปลงได้
ตัวแปรที่กำหนดโดยใช้ val คีย์เวิร์ดเป็นแบบอ่านอย่างเดียว ในขณะที่คีย์เวิร์ดที่กำหนดด้วย var สามารถอ่านและเปลี่ยนแปลงได้ในภายหลังโดยฟังก์ชันอื่น ๆ หรือโดยผู้ใช้ในโค้ด
var changeableVariable = 8 changeableVariable = 10 //the compiler does not complain, and the code compiles successfully println(changeableVariable) //10 val myNumber = 7 myNumber = 4 //this will not compile
พยายามกำหนดค่าให้กับ myNumber หลังจากประกาศว่าเป็น val ทำให้เกิดข้อผิดพลาดขณะคอมไพล์: “การกำหนดค่าใหม่ให้กับ val”
เหตุใดจึงใช้ความไม่เปลี่ยนรูป?
คุณสมบัติของค่าที่ไม่เปลี่ยนแปลงได้ ช่วยป้องกันไม่ให้โค้ดและโปรแกรมเมอร์คนอื่นๆ เปลี่ยนแปลงค่าโดยไม่คาดคิด ซึ่งจะนำไปสู่ผลลัพธ์ที่ไม่สามารถคาดเดาได้ หากผู้ใช้งานต้องการเปลี่ยนแปลงค่า พวกเขาสามารถสร้างสำเนาแทนได้ ด้วยวิธีนี้ จะช่วยป้องกันข้อผิดพลาดที่เกิดจากการที่ผู้ใช้งานหลายคนเปลี่ยนแปลงตัวแปรเดียวกัน
คลาสและวัตถุ
อ็อบเจ็กต์คือสิ่งที่มีอยู่จริงในโลกแห่งความเป็นจริง และคลาสคือแม่แบบที่ใช้กำหนดอ็อบเจ็กต์ คลาสมีทั้งสถานะและพฤติกรรม สถานะอาจเป็นค่าหรือตัวแปร ส่วนพฤติกรรมก็คือเมธอดในภาษา Scala
ส่วนถัดไปจะแสดงวิธีการกำหนดคลาส สร้างอินสแตนซ์ของคลาส และใช้งานคลาสในภาษา Scala
นี่คือคลาสชื่อ Rectangle ที่มีค่าสองค่าและฟังก์ชันสองฟังก์ชัน คุณสามารถใช้พารามิเตอร์ได้ด้วย l และ b โดยตรงเป็นฟิลด์ในโปรแกรม คุณมีอ็อบเจ็กต์ที่มีเมธอด main และสร้างอินสแตนซ์ของคลาสด้วยค่าสองค่า
ตัวอย่าง:
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 a rectangle with length $length and breadth $breadth" } object RectObject { def main(args: Array[String]) { val rect = new Rectangle(4, 5) println(rect.toString) println(rect.getArea) } }
โดยค่าเริ่มต้น ฟิลด์และเมธอดทั้งหมดใน Scala จะเป็นแบบสาธารณะ (public) การใช้งานอย่างถูกต้องนั้นมีความสำคัญมาก override เพราะ toString มีการกำหนดค่าไว้แล้วสำหรับทุกอ็อบเจ็กต์ใน Scala
มรดก
Scala มีรูปแบบการสืบทอดหลายประเภท (แบบเดี่ยว แบบหลายระดับ แบบหลายชั้น แบบลำดับชั้น และแบบผสม) ซึ่งมีลักษณะคล้ายคลึงกับรูปแบบดั้งเดิมที่พบในภาษาโปรแกรมทั่วไป Javaคุณสามารถสืบทอดได้ทั้งจากคลาสและจากคุณสมบัติ โดยคุณจะสืบทอดสมาชิกของคลาสหนึ่งไปยังอีกคลาสหนึ่งโดยใช้คำหลัก `herit` extendsซึ่งทำให้สามารถนำกลับมาใช้ใหม่ได้
สามารถสืบทอดคุณสมบัติจากคลาสเดียวหรือหลายคลาสก็ได้ นอกจากนี้ยังสามารถสืบทอดคุณสมบัติจากคลาสย่อยที่มีคลาสแม่ของตัวเองได้อีกด้วย ซึ่งจะสร้างลำดับชั้นของการสืบทอดขึ้นมา
ในตัวอย่าง Scala ด้านล่าง คลาสพื้นฐานคือ Circleและคลาสที่สืบทอดมาคือ Sphereวงกลมมีค่าที่เรียกว่ารัศมี ซึ่งเป็นค่าที่สืบทอดมาจากคลาส Sphere เมธอดนี้... calcArea ถูกแทนที่โดยใช้คีย์เวิร์ด override.
ตัวอย่าง:
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 } }
abstracการ
ใน Scala คุณสามารถสร้าง abs ได้tracวิธีการ t และฟิลด์สมาชิกโดยใช้ abstracคลาสและคุณลักษณะ t ภายใน abstracสำหรับคลาสและคุณลักษณะ คุณสามารถกำหนดค่าสัมบูรณ์ได้tracฟิลด์ t โดยไม่ต้องนำไปใช้งาน
ตัวอย่าง:
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" } }
ฟิลด์เหล่านี้ถูกนำไปใช้โดยคลาสที่ขยายคุณลักษณะหรือค่าสัมบูรณ์tracคลาส t คุณสามารถใช้คุณสมบัติเพื่อสร้างคอนได้tracกำหนดค่า ts สำหรับสิ่งที่แอปพลิเคชันควรทำ จากนั้นจึงนำวิธีการเหล่านั้นไปใช้งานในภายหลัง
trait DatabaseService { def addItemName(itemName:String) def removeItem(itemId:Int) def updateItem(itemId:Int, newItemName:String) }
ด้วยวิธีนี้ คุณสามารถวางแผนรูปลักษณ์ของแอปพลิเคชันได้โดยไม่ต้องลงมือเขียนเมธอดเหล่านั้นping คุณลองนึกภาพดูว่าวิธีการต่างๆ จะปรากฏขึ้นอย่างไร มันเป็นไปตามรูปแบบที่เรียกว่าการเขียนโปรแกรมเพื่อแก้ปัญหาtracมุ่งเน้นไปที่ข้อเสนอแนะมากกว่าการนำไปปฏิบัติจริง
ชั้นเรียนที่ขึ้นต้นด้วย abstract คำหลักสามารถประกอบด้วยทั้ง abstract และ non-abstracวิธีการ t อย่างไรก็ตาม abs ไม่รองรับการสืบทอดแบบหลายทางtracคลาส t ดังนั้นคุณจึงสามารถขยาย abs ได้เพียงคลาสเดียวเท่านั้นtracคลาส t
วัตถุซิงเกิลตัน
Singleton คือคลาสที่ถูกสร้างขึ้นเพียงครั้งเดียวในโปรแกรม มันมาจากรูปแบบการเขียนโปรแกรมยอดนิยมและมีประโยชน์ที่เรียกว่า "รูปแบบ Singleton" มันมีประโยชน์สำหรับการสร้างอินสแตนซ์ที่ตั้งใจให้มีอายุการใช้งานยาวนานและถูกเรียกใช้บ่อยๆ ตลอดทั้งโปรแกรม โดยที่สถานะมีความสำคัญต่อการประสานงานเหตุการณ์ในระบบ การสร้างคลาสแบบนี้ใน Scala นั้นง่าย เพราะ Scala มีวิธีการสร้าง Singleton ที่ง่ายโดยใช้ 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 ไม่มีแนวคิดเรื่องสมาชิกแบบ static ดังนั้นจึงต้องใช้ singleton object ซึ่งทำหน้าที่เหมือนสมาชิกแบบ static ของคลาส
ชั้นเรียนโดยปริยาย
คลาสโดยปริยาย (Implicit classes) เป็นคุณสมบัติที่เพิ่มเข้ามาในเวอร์ชัน 2.10 และใช้เป็นหลักในการเพิ่มฟังก์ชันการทำงานใหม่ให้กับคลาสแบบปิดที่มีอยู่เดิม
การขอ implicit คีย์เวิร์ดควรถูกกำหนดไว้ในคลาส อ็อบเจ็กต์ หรือเทรต คอนสตรัคเตอร์หลักของคลาสแบบอิมพลิซิตจะต้องมีอาร์กิวเมนต์เพียงหนึ่งเดียวในรายการพารามิเตอร์แรก นอกจากนี้ยังอาจมีรายการพารามิเตอร์แบบอิมพลิซิตเพิ่มเติมได้อีกด้วย
ในตัวอย่าง 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) โปรแกรมจะถูกสร้างขึ้นโดยกลุ่มping ข้อมูลและฟังก์ชันที่ทำงานกับข้อมูลนั้นถูกเชื่อมโยงเข้าด้วยกันอย่างแน่นหนา วัตถุจะเก็บข้อมูลไว้ในฟิลด์ และเมธอดจะทำงานกับฟิลด์เหล่านั้น ในรูปแบบการเขียนโปรแกรมแบบนี้ ส่วนประกอบหลักๆ คือ ข้อมูลและฟังก์ชันที่ทำงานกับข้อมูลtraction คือข้อมูล เพราะวิธีการที่ถูกสร้างขึ้นนั้นมีจุดประสงค์เพื่อใช้งานกับข้อมูล
การเขียนโปรแกรมเชิงฟังก์ชันในทางกลับกัน การแยกข้อมูลและฟังก์ชันที่ทำงานกับข้อมูลนั้นออกจากกัน ทำให้ผู้พัฒนาสามารถมองฟังก์ชันเป็นเหมือนค่าสัมบูรณ์ได้tracแนวคิดและแรงผลักดันเมื่อสร้างแบบจำลองโปรแกรม
Scala ช่วยให้การเขียนโปรแกรมเชิงฟังก์ชันเป็นไปได้ง่ายขึ้น โดยการถือว่าฟังก์ชันเป็นองค์ประกอบสำคัญ ทำให้สามารถส่งฟังก์ชันเป็นค่าไปยังฟังก์ชันอื่น และรับฟังก์ชันกลับเป็นค่าได้เช่นกัน การผสมผสานระหว่างสองแนวคิดนี้ทำให้ Scala เป็นตัวเลือกที่ดีเยี่ยมสำหรับการสร้างซอฟต์แวร์ที่ซับซ้อนในอุตสาหกรรมต่างๆ เช่น วิทยาศาสตร์ข้อมูล
กรอบการทำงานที่สำคัญบน Scala
ต่อไปนี้คือเฟรมเวิร์กที่สำคัญบางส่วนสำหรับ Scala:
- เล่น เป็นเฟรมเวิร์กแอปพลิเคชันเว็บแบบโอเพ่นซอร์สที่ใช้ สถาปัตยกรรม MVCเปิดตัวในปี 2007 และปัจจุบันได้รับอนุญาตภายใต้ Apache กลายเป็นหนึ่งในเฟรมเวิร์กที่ได้รับความนิยมมากที่สุดบน GitHub ในปี 2013 บริษัทต่างๆ เช่น LinkedIn, WalmartSamsung และ Eero ใช้เฟรมเวิร์กนี้
- ยก Lift เป็นเฟรมเวิร์กเว็บฟรีอีกตัวหนึ่งที่เขียนด้วยภาษา Scala เปิดตัวในปี 2007 Foursquare ใช้เฟรมเวิร์ก Lift ซึ่งเป็นเฟรมเวิร์กประสิทธิภาพสูงและสร้างได้รวดเร็ว
- อัคคะ มีเครื่องมือสำหรับสร้างแอปพลิเคชันที่ขับเคลื่อนด้วยข้อความซึ่งมีความสามารถในการทำงานพร้อมกันสูง กระจายตัว และมีความยืดหยุ่นสูงบน JVM
- แมว เป็นห้องสมุดที่ให้บริการ abstracข้อเสนอแนะสำหรับการเขียนโปรแกรมเชิงฟังก์ชัน
- Spark เป็นเอนจินวิเคราะห์ข้อมูลแบบครบวงจรสำหรับการประมวลผลข้อมูลขนาดใหญ่ ซึ่งใช้กันอย่างแพร่หลายในเวิร์กโฟลว์ข้อมูลขนาดใหญ่และการเรียนรู้ของเครื่อง
การสนับสนุนพร้อมกัน
- โดยค่าเริ่มต้น ค่าต่างๆ ใน Scala จะไม่สามารถเปลี่ยนแปลงได้ ซึ่งทำให้สามารถปรับตัวเข้ากับสภาพแวดล้อมที่มีการทำงานพร้อมกันได้เป็นอย่างดี
- Scala มีคุณสมบัติหลายอย่างที่ทำให้เหมาะอย่างยิ่งสำหรับแอปพลิเคชันที่ทำงานพร้อมกันหลายฝ่าย
- สัญญาซื้อขายล่วงหน้าและสัญญาทำให้การประมวลผลข้อมูลแบบอะซิงโครนัสง่ายขึ้น จึงรองรับการทำงานแบบคู่ขนาน
- Akka เป็นชุดเครื่องมือที่ใช้โมเดลการทำงานพร้อมกันแบบ Actor โดย Actor จะทำงานเมื่อได้รับข้อความ
- เห็นพ้องต้องกันโดยใช้เธรดจาก Java นอกจากนี้ยังรองรับในภาษา Scala ด้วย
- การประมวลผลแบบสตรีมเป็นอีกหนึ่งคุณสมบัติที่ยอดเยี่ยม ซึ่งช่วยให้สามารถประมวลผลข้อมูลได้อย่างต่อเนื่องและแบบเรียลไทม์
Scala มีไลบรารีการทำงานพร้อมกันที่ดีที่สุดบางส่วนใน Java ระบบนิเวศ:
- พื้นเมือง Java หัวข้อ
- ข้อมูลจากไลบรารีต่างๆ เช่น Vertx
- ZIO คือไลบรารีที่มีฟังก์ชันพื้นฐานเพื่อช่วยจัดการกับการทำงานพร้อมกันและการคำนวณแบบอะซิงโครนัส
- หน่วยความจำธุรกรรมซอฟต์แวร์ (STM) สำหรับธุรกรรมต่างๆ
- Future ซึ่งเป็นคุณสมบัติที่มีอยู่ในภาษา Scala
Java ปะทะสกาล่า
นี่คือหลัก ความแตกต่างระหว่าง Java และสกาล่า.
| สกาล่า | Java |
|---|---|
| กระชับและสั้นกว่า | โค้ดที่มีขนาดใหญ่กว่าเมื่อเทียบกัน |
| ออกแบบและพัฒนาให้เป็นทั้งภาษาเชิงวัตถุและเชิงฟังก์ชัน รองรับคุณสมบัติการเขียนโปรแกรมเชิงฟังก์ชันที่หลากหลาย เช่น การทำงานพร้อมกันและความไม่เปลี่ยนแปลงของข้อมูล | เดิมทีพัฒนาขึ้นเป็นภาษาเชิงวัตถุ และเริ่มรองรับคุณสมบัติการเขียนโปรแกรมเชิงฟังก์ชันในเวอร์ชันล่าสุด อย่างไรก็ตาม ยังไม่แข็งแกร่งเท่า Scala ในด้านการเขียนโปรแกรมเชิงฟังก์ชัน |
| ใช้โมเดล Actor เพื่อรองรับการทำงานพร้อมกัน | ใช้โมเดลแบบเกลียวทั่วไปเพื่อให้ทำงานพร้อมกันได้ |
| รองรับเฟรมเวิร์กต่างๆ เช่น Play และ Lift | รองรับ Spring, Grails และอื่นๆ อีกมากมาย |
| รองรับการประเมินแบบเลซี่ (Lazy Evaluation) | ฟังก์ชันนี้ไม่รองรับการประเมินแบบเลซี่ (lazy evaluation) โดยตรง |
| ไม่มีสมาชิกแบบคงที่ | ประกอบด้วยสมาชิกแบบคงที่ |
| รองรับการทำงานเกินกำลังของผู้ปฏิบัติงาน | ไม่รองรับการใช้งานเกินกำลังของผู้ปฏิบัติงาน |
| การคอมไพล์ซอร์สโค้ดค่อนข้างช้า | การคอมไพล์ซอร์สโค้ดเร็วกว่า Scala |
| ลักษณะเฉพาะทำหน้าที่เหมือน Java อินเทอร์เฟซ 8 ช่อง | Java อินเทอร์เฟซทั้ง 8 แบบพยายามเชื่อมช่องว่างระหว่างคลาสและอินเทอร์เฟซ |
| บางครั้งจำเป็นต้องเขียนโค้ดใหม่เมื่ออัปเกรดเวอร์ชัน | โดยทั่วไปแล้วไม่จำเป็นต้องเขียนโค้ดใหม่ระหว่างเวอร์ชันต่างๆ |
| การตรวจสอบประเภทข้อมูลช่วยให้โค้ดมีความน่าเชื่อถือสูง แต่ก็ไม่ได้รับประกันว่าจะปราศจากข้อผิดพลาดโดยสิ้นเชิง | สถิตที่แข็งแกร่งping ช่วยลดข้อผิดพลาดขณะรันไทม์ได้หลายประการ |
| มีข้อจำกัดบางประการเกี่ยวกับการใช้งานร่วมกับเวอร์ชันหลักรุ่นเก่า | รองรับการใช้งานร่วมกับเวอร์ชันเก่าได้อย่างดีเยี่ยมในระยะยาว |
| Operaทอร์จะถูกมองว่าเป็นการเรียกใช้เมธอด | Operators เป็นไวยากรณ์พิเศษและไม่ใช่การเรียกใช้เมธอด |
| รองรับการสืบทอดแบบหลายทางโดยใช้ลักษณะเฉพาะ (traits) | ไม่รองรับการสืบทอดแบบหลายทางโดยใช้คลาส แต่ใช้อินเทอร์เฟซแทน |
| Code เขียนในรูปแบบที่กระชับ | Code เขียนด้วยรูปแบบที่ละเอียดกว่า |
| Scala ไม่มีคำหลักแบบคงที่ | Java มีคำหลักแบบคงที่ |






















