Định nghĩa lớp:
val
hoặc var
có thể được bỏ qua khỏi các tham số lớp sẽ làm cho tham số này trở thành riêng tư.
Thêm var hoặc val sẽ làm cho nó ở chế độ công khai (nghĩa là các trình truy cập phương thức và trình đột biến được tạo).
{}
có thể bị bỏ qua nếu lớp không có nội dung, nghĩa là
class EmptyClass
Khởi tạo lớp:
Các tham số chung có thể được bỏ qua nếu chúng có thể được trình biên dịch suy ra. Tuy nhiên, lưu ý rằng nếu các kiểu của bạn không khớp, thì tham số kiểu luôn được suy ra để nó khớp. Vì vậy, nếu không chỉ định loại, bạn có thể không nhận được những gì bạn mong đợi - nghĩa là
class D[T](val x:T, val y:T);
Điều này sẽ cung cấp cho bạn một lỗi loại (Tìm thấy Int, Chuỗi dự kiến)
var zz = new D[String]("Hi1", 1) // type error
Trong khi điều này hoạt động tốt:
var z = new D("Hi1", 1)
== D{def x: Any; def y: Any}
Bởi vì tham số kiểu, T, được suy ra là siêu kiểu phổ biến nhất trong hai kiểu - Bất kỳ.
Định nghĩa hàm:
=
có thể bị loại bỏ nếu hàm trả về Đơn vị (không có gì).
{}
đối với phần thân hàm có thể bị loại bỏ nếu hàm là một câu lệnh đơn lẻ, nhưng chỉ khi câu lệnh trả về một giá trị (bạn cần =
dấu), nghĩa là
def returnAString = "Hi!"
nhưng điều này không hoạt động:
def returnAString "Hi!" // Compile error - '=' expected but string literal found."
Kiểu trả về của hàm có thể được bỏ qua nếu nó có thể được suy ra (một phương thức đệ quy phải có kiểu trả về được chỉ định).
()
có thể bị loại bỏ nếu hàm không nhận bất kỳ đối số nào, nghĩa là
def endOfString {
return "myDog".substring(2,1)
}
theo quy ước được dành riêng cho các phương pháp không có tác dụng phụ - sau này sẽ nói thêm về điều đó.
()
không thực sự bị bỏ qua khi xác định tham số truyền theo tên , nhưng nó thực sự là một ký hiệu hoàn toàn khác về mặt ngữ nghĩa, nghĩa là
def myOp(passByNameString: => String)
Nói myOp nhận tham số truyền theo tên, dẫn đến một Chuỗi (nghĩa là, nó có thể là một khối mã trả về một chuỗi) trái ngược với các tham số hàm,
def myOp(functionParam: () => String)
trong đó cho biết myOp
nhận một hàm không có tham số và trả về một Chuỗi.
(Xin lưu ý bạn, các tham số tên truyền được biên dịch thành các hàm; nó chỉ làm cho cú pháp đẹp hơn.)
()
có thể bị loại bỏ trong định nghĩa tham số hàm nếu hàm chỉ nhận một đối số, ví dụ:
def myOp2(passByNameString:(Int) => String) { .. } // - You can drop the ()
def myOp2(passByNameString:Int => String) { .. }
Nhưng nếu nó chiếm nhiều hơn một đối số, bạn phải bao gồm ():
def myOp2(passByNameString:(Int, String) => String) { .. }
Các câu lệnh:
.
có thể được bỏ để sử dụng ký hiệu toán tử, chỉ có thể được sử dụng cho các toán tử infix (toán tử của phương thức nhận đối số). Xem câu trả lời của Daniel để biết thêm thông tin.
.
cũng có thể được bỏ cho đuôi danh sách chức năng postfix
()
có thể được bỏ cho các toán tử postfix list.tail
()
không thể được sử dụng với các phương thức được định nghĩa là:
def aMethod = "hi!" // Missing () on method definition
aMethod // Works
aMethod() // Compile error when calling method
Bởi vì ký hiệu này được quy ước dành riêng cho các phương thức không có tác dụng phụ, như đuôi List # (nghĩa là, việc gọi một hàm không có tác dụng phụ có nghĩa là hàm không có tác dụng quan sát được, ngoại trừ giá trị trả về của nó).
()
có thể bị loại bỏ cho ký hiệu toán tử khi truyền vào một đối số duy nhất
()
có thể được yêu cầu sử dụng các toán tử hậu tố không nằm ở cuối câu lệnh
()
có thể được yêu cầu để chỉ định các câu lệnh lồng nhau, phần cuối của các hàm ẩn danh hoặc cho các toán tử nhận nhiều hơn một tham số
Khi gọi một hàm có một hàm, bạn không thể bỏ qua () khỏi định nghĩa hàm bên trong, ví dụ:
def myOp3(paramFunc0:() => String) {
println(paramFunc0)
}
myOp3(() => "myop3") // Works
myOp3(=> "myop3") // Doesn't work
Khi gọi một hàm có tham số tên, bạn không thể chỉ định đối số là một hàm ẩn danh ít tham số. Ví dụ, đã cho:
def myOp2(passByNameString:Int => String) {
println(passByNameString)
}
Bạn phải gọi nó là:
myOp("myop3")
hoặc là
myOp({
val source = sourceProvider.source
val p = myObject.findNameFromSource(source)
p
})
nhưng không:
myOp(() => "myop3") // Doesn't work
IMO, lạm dụng việc bỏ các loại trả lại có thể gây hại cho việc sử dụng lại mã. Chỉ cần nhìn vào đặc điểm kỹ thuật để biết một ví dụ điển hình về việc giảm khả năng đọc do thiếu thông tin rõ ràng trong mã. Số lượng mức độ chuyển hướng để thực sự tìm ra loại biến là gì có thể rất nhỏ. Hy vọng rằng các công cụ tốt hơn có thể ngăn chặn vấn đề này và giữ cho mã của chúng tôi ngắn gọn.
(OK, trong nhiệm vụ biên soạn một câu trả lời ngắn gọn, đầy đủ hơn (nếu tôi bỏ sót bất cứ điều gì hoặc có điều gì sai / không chính xác, vui lòng bình luận), tôi đã thêm vào đầu câu trả lời. Xin lưu ý rằng đây không phải là ngôn ngữ đặc điểm kỹ thuật, vì vậy tôi không cố gắng làm cho nó chính xác về mặt học thuật - giống như một thẻ tham khảo hơn.)