ฉันพยายามเขียนเกี่ยวกับสิ่งนี้ แต่ฉันก็ยอมแพ้ในที่สุดเนื่องจากกฎกติกาค่อนข้างกระจายออกไป โดยทั่วไปคุณจะต้องได้รับการแขวนของมัน
อาจเป็นการดีที่สุดที่จะจดจ่อกับตำแหน่งที่วงเล็บปีกกาและวงเล็บสามารถใช้แทนกันได้: เมื่อส่งพารามิเตอร์ไปยังการเรียกเมธอด คุณสามารถแทนที่วงเล็บด้วยเครื่องหมายปีกกาถ้าและวิธีการที่คาดว่าจะเป็นพารามิเตอร์เดียว ตัวอย่างเช่น:
List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter
List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
อย่างไรก็ตามคุณจำเป็นต้องรู้เพื่อให้เข้าใจกฎเหล่านี้ได้ดีขึ้น
เพิ่มการตรวจสอบคอมไพล์ด้วย parens
ผู้เขียนของสเปรย์แนะนำ parens รอบเพราะพวกเขาให้การตรวจสอบที่รวบรวมเพิ่มขึ้น สิ่งนี้สำคัญอย่างยิ่งสำหรับ DSL เช่นสเปรย์ โดยใช้ parens คุณกำลังบอกคอมไพเลอร์ว่าควรให้เพียงบรรทัดเดียวเท่านั้น ดังนั้นหากคุณให้สองคนขึ้นไปโดยไม่ตั้งใจมันจะบ่น ตอนนี้นี่ไม่ใช่กรณีที่มีเครื่องหมายปีกกา - ตัวอย่างเช่นคุณลืมผู้ประกอบการบางแห่งแล้วรหัสของคุณจะรวบรวมและคุณได้รับผลลัพธ์ที่ไม่คาดคิดและอาจเป็นข้อผิดพลาดที่หายากมาก ด้านล่างนี้มีการวางแผน (เนื่องจากการแสดงออกมีความบริสุทธิ์และอย่างน้อยก็จะเตือน) แต่ทำให้ประเด็น:
method {
1 +
2
3
}
method(
1 +
2
3
)
error: ')' expected but integer literal found
คอมไพล์ครั้งแรกที่สองให้ ผู้เขียนต้องการเขียน1 + 2 + 3
ผู้เขียนอยากจะเขียน
หนึ่งอาจโต้แย้งว่ามันคล้ายกันสำหรับวิธีการหลายพารามิเตอร์ที่มีข้อโต้แย้งเริ่มต้น เป็นไปไม่ได้ที่จะลืมเครื่องหมายจุลภาคโดยไม่ตั้งใจแยกพารามิเตอร์เมื่อใช้ parens
การใช้คำฟุ่มเฟื่อย
บันทึกย่อที่สำคัญที่มักถูกมองข้ามเกี่ยวกับการใช้คำฟุ่มเฟื่อย การใช้วงเล็บปีกกาอย่างหลีกเลี่ยงไม่ได้นำไปสู่การสร้างรหัส verbose เนื่องจากคู่มือสไตล์สกาล่าอย่างชัดเจนระบุว่าวงเล็บปีกกาปิดต้องอยู่ในบรรทัดของตัวเอง:
... วงเล็บปีกกาปิดอยู่บนบรรทัดของตัวเองทันทีหลังจากบรรทัดสุดท้ายของฟังก์ชัน
การจัดรูปแบบอัตโนมัติจำนวนมากเช่นเดียวกับใน IntelliJ จะทำการฟอร์แมตใหม่โดยอัตโนมัติสำหรับคุณ ดังนั้นพยายามที่จะใช้ parens รอบเมื่อคุณสามารถ
สัญกรณ์ผูก
เมื่อใช้สัญกรณ์ infix เช่นList(1,2,3) indexOf (2)
คุณสามารถละเว้นวงเล็บถ้ามีเพียงหนึ่งพารามิเตอร์และเขียนเป็นList(1, 2, 3) indexOf 2
คุณสามารถละเว้นวงเล็บถ้ามีเพียงหนึ่งพารามิเตอร์และเขียนเป็นนี่ไม่ใช่กรณีของเครื่องหมายจุด
โปรดทราบว่าเมื่อคุณมีพารามิเตอร์เดียวที่เป็นนิพจน์แบบหลายโทเค็นเช่นx + 2
หรือa => a % 2 == 0
คุณต้องใช้วงเล็บเพื่อระบุขอบเขตของการแสดงออก
tuples
เพราะคุณสามารถละเว้นวงเล็บบางครั้งบางครั้ง tuple ต้องการวงเล็บพิเศษเช่นใน และบางครั้งวงเล็บด้านนอกสามารถละเว้นเหมือนใน((1, 2))
(1, 2)
นี่อาจทำให้เกิดความสับสน
ฟังก์ชั่น / ตัวอักษรฟังก์ชั่นบางส่วนด้วย case
Scala มีไวยากรณ์สำหรับฟังก์ชันและฟังก์ชันตัวอักษรบางส่วน ดูเหมือนว่านี้:
{
case pattern if guard => statements
case pattern => statements
}
สถานที่อื่น ๆ ที่คุณสามารถใช้case
คำสั่งได้คือกับmatch
และcatch
คำหลัก:
object match {
case pattern if guard => statements
case pattern => statements
}
try {
block
} catch {
case pattern if guard => statements
case pattern => statements
} finally {
block
}
คุณไม่สามารถใช้case
งบในบริบทอื่น ๆ ดังนั้นถ้าคุณต้องการใช้case
คุณต้อง จัดฟันแบบหยิก ในกรณีที่คุณสงสัยว่าอะไรทำให้เกิดความแตกต่างระหว่างฟังก์ชั่นและฟังก์ชั่นบางส่วนตามตัวอักษรคำตอบคือ: บริบท หาก Scala คาดว่าจะมีฟังก์ชั่นเป็นฟังก์ชั่นที่คุณจะได้รับ ถ้ามันคาดว่าจะมีฟังก์ชั่นบางส่วนคุณจะได้รับฟังก์ชั่นบางส่วน หากคาดว่าทั้งคู่จะทำให้เกิดข้อผิดพลาดเกี่ยวกับความกำกวม
นิพจน์และบล็อก
วงเล็บสามารถนำมาใช้เพื่อสร้างนิพจน์ย่อย วงเล็บปีกกาสามารถใช้เพื่อสร้างบล็อกของรหัส (นี่ไม่ใช่ฟังก์ชั่นตามตัวอักษรดังนั้นระวังการใช้มันเหมือนมัน) บล็อกของรหัสประกอบด้วยหลายงบซึ่งแต่ละอันสามารถเป็นคำสั่งนำเข้าการประกาศหรือการแสดงออก มันจะเป็นเช่นนี้:
{
import stuff._
statement ; // ; optional at the end of the line
statement ; statement // not optional here
var x = 0 // declaration
while (x < 10) { x += 1 } // stuff
(x % 5) + 1 // expression
}
( expression )
ดังนั้นหากคุณต้องการการประกาศหลาย ๆ คำสั่งimport
หรืออะไรทำนองนั้นคุณจำเป็นต้องมีเครื่องหมายปีกกา และเนื่องจากการแสดงออกเป็นคำสั่งวงเล็บอาจปรากฏขึ้นภายในวงเล็บปีกกา แต่สิ่งที่น่าสนใจคือบล็อคของรหัสนั้นก็มีการแสดงออกดังนั้นคุณสามารถใช้มันได้ทุกที่ภายในนิพจน์:
( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
ดังนั้นเนื่องจากการแสดงออกเป็นงบและบล็อกของรหัสเป็นนิพจน์ทุกอย่างด้านล่างนี้ถูกต้อง:
1 // literal
(1) // expression
{1} // block of code
({1}) // expression with a block of code
{(1)} // block of code with an expression
({(1)}) // you get the drift...
พวกเขาจะไม่สามารถใช้แทนกันได้
โดยทั่วไปคุณไม่สามารถแทนที่{}
ด้วย()
หรือกลับกันได้ทุกที่ ตัวอย่างเช่น:
while (x < 10) { x += 1 }
นี่ไม่ใช่การเรียกใช้เมธอดดังนั้นคุณจึงไม่สามารถเขียนด้วยวิธีอื่นได้ คุณสามารถใส่วงเล็บปีกกาไว้ในวงเล็บสำหรับcondition
หรือใช้วงเล็บในวงเล็บปีกกาสำหรับบล็อกของรหัส:
while ({x < 10}) { (x += 1) }
ดังนั้นฉันหวังว่านี่จะช่วยได้