Các quy tắc chính xác là gì khi bạn có thể bỏ qua dấu ngoặc đơn, dấu chấm, dấu ngoặc nhọn, = (hàm), v.v.?


106

Các quy tắc chính xác là gì khi bạn có thể bỏ qua (bỏ qua) dấu ngoặc đơn, dấu chấm, dấu ngoặc nhọn, = (hàm), v.v.?

Ví dụ,

(service.findAllPresentations.get.first.votes.size) must be equalTo(2).
  • service là đối tượng của tôi
  • def findAllPresentations: Option[List[Presentation]]
  • votes trả lại List[Vote]
  • phảiphải là cả hai chức năng của thông số kỹ thuật

Tại sao tôi không thể đi:

(service findAllPresentations get first votes size) must be equalTo(2)

?

Lỗi trình biên dịch là:

"RestServicesSpecTest.this.service.findAllPresentations loại Tùy chọn [Danh sách [com.sharca.Presentation]] không nhận tham số"

Tại sao nó nghĩ rằng tôi đang cố gắng truyền một tham số? Tại sao tôi phải sử dụng dấu chấm cho mọi lệnh gọi phương thức?

Tại sao phải (service.findAllPresentations get first votes size)bằng nhau Để (2) dẫn đến:

"không tìm thấy: giá trị đầu tiên"

Tuy nhiên, "must be bằngTo 2" của (service.findAllPresentations.get.first.votes.size)phải bằngTo 2, nghĩa là, chuỗi phương thức hoạt động tốt? - chuỗi đối tượng chuỗi tham số chuỗi.

Tôi đã xem qua sách và trang web của Scala và thực sự không thể tìm thấy lời giải thích toàn diện.

Thực tế có phải như vậy, như Rob H giải thích trong câu hỏi Stack Overflow Tôi có thể bỏ qua những ký tự nào trong Scala? , đó là trường hợp sử dụng hợp lệ duy nhất để bỏ qua dấu '.' là cho các phép toán kiểu "toán hạng toán hạng", và không cho chuỗi phương thức?

Câu trả lời:


87

Bạn dường như đã vấp phải câu trả lời. Dù sao thì, tôi sẽ cố gắng nói rõ.

Bạn có thể bỏ qua dấu chấm khi sử dụng ký hiệu tiền tố, tiền tố và hậu tố - cái gọi là ký hiệu toán tử . Trong khi sử dụng ký hiệu toán tử, và chỉ sau đó, bạn có thể bỏ qua dấu ngoặc đơn nếu có ít hơn hai tham số được truyền cho phương thức.

Bây giờ, ký hiệu toán tử là ký hiệu cho cuộc gọi phương thức , có nghĩa là nó không thể được sử dụng khi không có đối tượng đang được gọi.

Tôi sẽ trình bày chi tiết ngắn gọn về các ký hiệu.

Tiếp đầu ngữ:

Chỉ ~, !, +-có thể được sử dụng trong tiền tố ký hiệu. Đây là ký hiệu bạn đang sử dụng khi viết !flaghoặc val liability = -debt.

Tiền tố:

Đó là ký hiệu nơi phương thức xuất hiện giữa một đối tượng và các tham số của nó. Các toán tử số học đều phù hợp ở đây.

Postfix (cũng là hậu tố):

Ký hiệu đó được sử dụng khi phương thức theo sau một đối tượng và không nhận được tham số nào . Ví dụ, bạn có thể viết list tail, và đó là ký hiệu hậu tố.

Bạn có thể xâu chuỗi các lệnh gọi ký hiệu infix mà không có vấn đề gì, miễn là không có phương thức nào được xử lý. Ví dụ, tôi thích sử dụng kiểu sau:

(list
 filter (...)
 map (...)
 mkString ", "
)

Đó là điều tương tự như:

list filter (...) map (...) mkString ", "

Bây giờ, tại sao tôi lại sử dụng dấu ngoặc ở đây, nếu bộ lọc và bản đồ có một tham số duy nhất? Đó là bởi vì tôi đang chuyển các chức năng ẩn danh cho họ. Tôi không thể kết hợp các định nghĩa hàm ẩn danh với kiểu infix vì tôi cần một ranh giới cho phần cuối của hàm ẩn danh của mình. Ngoài ra, định nghĩa tham số của hàm ẩn danh có thể được hiểu là tham số cuối cùng của phương thức infix.

Bạn có thể sử dụng infix với nhiều tham số:

string substring (start, end) map (_ toInt) mkString ("<", ", ", ">")

Khó sử dụng các hàm có mã hóa với ký hiệu infix. Các chức năng gấp là một ví dụ rõ ràng về điều đó:

(0 /: list) ((cnt, string) => cnt + string.size)
(list foldLeft 0) ((cnt, string) => cnt + string.size)

Bạn cần sử dụng dấu ngoặc đơn bên ngoài lời gọi infix. Tôi không chắc luật chơi chính xác ở đây.

Bây giờ, hãy nói về postfix. Postfix có thể khó sử dụng, vì nó không bao giờ có thể được sử dụng ở bất kỳ đâu ngoại trừ phần cuối của một biểu thức . Ví dụ: bạn không thể làm như sau:

 list tail map (...)

Bởi vì đuôi không xuất hiện ở cuối biểu thức. Bạn cũng không thể làm điều này:

 list tail length

Bạn có thể sử dụng ký hiệu infix bằng cách sử dụng dấu ngoặc đơn để đánh dấu phần cuối của biểu thức:

 (list tail) map (...)
 (list tail) length

Lưu ý rằng ký hiệu hậu tố không được khuyến khích vì nó có thể không an toàn .

Tôi hy vọng điều này đã giải tỏa tất cả những nghi ngờ. Nếu không, chỉ cần thả một bình luận và tôi sẽ xem những gì tôi có thể làm để cải thiện nó.


ahh, vì vậy bạn đang nói rằng trong tuyên bố của tôi: (((((((((((((((thực)) realService findAllPresentations) get) first) kích thước)) phải bằng nhau ? vì vậy tôi tự hỏi điều gì phải, được và equalTo là ...
Antony Stubbs

Tôi không nói gì thuộc về loại này, mặc dù tôi khá chắc chắn rằng phải như vậy. :-) "be" có lẽ là một đối tượng trợ giúp, để làm cho cú pháp đẹp hơn. Hoặc, cụ thể hơn, để cho phép sử dụng ký hiệu infix với "must".
Daniel C. Sobral

Tốt thôi là Option.get, Đầu tiên là list.first, phiếu bầu là thuộc tính lớp trường hợp và kích thước là list.size. Bây giờ bạn đang nghĩ gì?
Antony Stubbs

À vâng - tất cả điều này được củng cố bởi thực tế là "(realService findPresentation 1) .get.id phải bằngTo 1" hoạt động - vì có vẻ như Service # findPresentations (id: Int) là một toán tử infix. Tuyệt - Tôi nghĩ rằng tôi đã hiểu nó ngay bây giờ. :)
Antony Stubbs

42

Định nghĩa lớp:

valhoặc varcó 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 myOpnhậ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.)


10
Tôi đang khóc. Cái này là cái gì.
Profpatsch

12

Một bộ sưu tập các trích dẫn cung cấp cái nhìn sâu sắc về các điều kiện khác nhau ...

Cá nhân tôi nghĩ rằng sẽ có nhiều hơn trong thông số kỹ thuật. Tôi chắc chắn phải có, tôi chỉ đang không tìm kiếm những từ thích hợp ...

Tuy nhiên, có một vài nguồn và tôi đã thu thập chúng cùng nhau, nhưng không có gì thực sự đầy đủ / toàn diện / dễ hiểu / giải thích cho tôi những vấn đề trên ...:

"Nếu thân phương thức có nhiều hơn một biểu thức, bạn phải bao quanh nó bằng dấu ngoặc nhọn {…}. Bạn có thể bỏ qua dấu ngoặc nhọn nếu thân phương thức chỉ có một biểu thức."

Từ chương 2, "Nhập ít hơn, làm nhiều hơn", của Lập trình Scala :

"Phần thân của phương thức trên đứng sau dấu bằng '='. Tại sao lại là dấu bằng? Tại sao không chỉ là dấu ngoặc nhọn {…}, như trong Java? Bởi vì dấu chấm phẩy, kiểu trả về của hàm, danh sách đối số của phương thức và thậm chí cả dấu ngoặc nhọn Đôi khi bị bỏ qua, việc sử dụng dấu bằng ngăn chặn một số mơ hồ phân tích cú pháp có thể xảy ra. Sử dụng dấu bằng cũng nhắc chúng ta rằng các hàm chẵn là giá trị trong Scala, điều này phù hợp với sự hỗ trợ của Scala về lập trình hàm, được mô tả chi tiết hơn trong Chương 8, Lập trình hàm trong Scala. "

Từ chương 1, "Zero to Sixty: Giới thiệu Scala", của Lập trình Scala :

"Một hàm không có tham số có thể được khai báo mà không có dấu ngoặc đơn, trong trường hợp đó nó phải được gọi mà không có dấu ngoặc đơn. Điều này cung cấp hỗ trợ cho Nguyên tắc truy cập thống nhất, sao cho người gọi không biết liệu biểu tượng là một biến hay một hàm không có thông số.

Thân hàm được đặt trước "=" nếu nó trả về một giá trị (tức là kiểu trả về không phải là Đơn vị), nhưng kiểu trả về và dấu "=" có thể bị bỏ qua khi kiểu là Đơn vị (tức là nó trông giống như một thủ tục trái ngược với một chức năng).

Không bắt buộc phải niềng răng xung quanh cơ thể (nếu cơ thể là một biểu hiện đơn lẻ); chính xác hơn, phần thân của một hàm chỉ là một biểu thức và bất kỳ biểu thức nào có nhiều phần đều phải được đặt trong dấu ngoặc nhọn (một biểu thức có một phần có thể được đặt trong dấu ngoặc nhọn). "

"Các hàm có 0 hoặc một đối số có thể được gọi mà không có dấu chấm và dấu ngoặc đơn. Nhưng bất kỳ biểu thức nào cũng có thể có dấu ngoặc đơn xung quanh, vì vậy bạn có thể bỏ qua dấu chấm và vẫn sử dụng dấu ngoặc đơn.

Và vì bạn có thể sử dụng dấu ngoặc nhọn ở bất cứ đâu bạn có thể sử dụng dấu ngoặc đơn, bạn có thể bỏ qua dấu chấm và đặt trong dấu ngoặc nhọn, có thể chứa nhiều câu lệnh.

Các hàm không có đối số có thể được gọi mà không có dấu ngoặc đơn. Ví dụ, hàm length () trên Chuỗi có thể được gọi là "abc" .length thay vì "abc" .length (). Nếu hàm là một hàm Scala được định nghĩa không có dấu ngoặc đơn thì hàm phải được gọi mà không có dấu ngoặc đơn.

Theo quy ước, các hàm không có đối số có tác dụng phụ, chẳng hạn như println, được gọi với dấu ngoặc đơn; những loại không có tác dụng phụ được gọi là không có dấu ngoặc đơn. "

Từ bài đăng trên blog Scala Syntax Primer :

"Định nghĩa thủ tục là một định nghĩa hàm trong đó kiểu kết quả và dấu bằng bị bỏ qua; biểu thức xác định của nó phải là một khối. Ví dụ: def f (ps) {stats} tương đương với def f (ps): Unit = {stats }.

Ví dụ 4.6.3 Đây là một khai báo và định nghĩa của một thủ tục có tên là write:

trait Writer {
    def write(str: String)
}
object Terminal extends Writer {
    def write(str: String) { System.out.println(str) }
}

Đoạn mã trên được hoàn thành ngầm thành đoạn mã sau:

trait Writer {
    def write(str: String): Unit
}
object Terminal extends Writer {
    def write(str: String): Unit = { System.out.println(str) }
}"

Từ đặc tả ngôn ngữ:

"Với các phương thức chỉ nhận một tham số duy nhất, Scala cho phép nhà phát triển thay thế. Bằng dấu cách và bỏ qua dấu ngoặc đơn, cho phép cú pháp toán tử được hiển thị trong ví dụ về toán tử chèn của chúng tôi. Cú pháp này được sử dụng ở những nơi khác trong API Scala, chẳng hạn như khi xây dựng các trường hợp Phạm vi:

val firstTen:Range = 0 to 9

Ở đây một lần nữa, to (Int) là một phương thức vani được khai báo bên trong một lớp (thực sự có một số chuyển đổi kiểu ngầm định hơn ở đây, nhưng bạn sẽ hiểu sai). "

Từ Scala cho người tị nạn Java Phần 6: Vượt qua Java :

"Bây giờ, khi bạn thử" m 0 ", Scala loại bỏ nó là toán tử một ngôi, với lý do không phải là một toán tử hợp lệ (~,!, - và +). Nó nhận thấy rằng" m "là một đối tượng hợp lệ - nó là một hàm, không phải là một phương thức, và tất cả các hàm đều là đối tượng.

Vì "0" không phải là số nhận dạng Scala hợp lệ, nên nó không thể là đầu vào hay toán tử hậu tố. Do đó, Scala phàn nàn rằng nó mong đợi ";" - sẽ phân tách hai (gần như) biểu thức hợp lệ: "m" và "0". Nếu bạn đã chèn nó, thì nó sẽ phàn nàn rằng m yêu cầu một đối số hoặc, nếu không, "_" để biến nó thành một hàm được áp dụng một phần. "

"Tôi tin rằng kiểu cú pháp toán tử chỉ hoạt động khi bạn có một đối tượng rõ ràng ở phía bên trái. Cú pháp nhằm cho phép bạn diễn đạt các thao tác kiểu" toán hạng toán hạng "theo cách tự nhiên."

Tôi có thể bỏ qua những ký tự nào trong Scala?

Nhưng điều cũng làm tôi bối rối là câu trích dẫn này:

"Cần phải có một đối tượng để nhận một cuộc gọi phương thức. Ví dụ: bạn không thể thực hiện" println "Hello World!" "Vì println cần một người nhận đối tượng. Bạn có thể thực hiện “Console println“ Hello World! ”" Để đáp ứng nhu cầu. "

Bởi vì như xa như tôi có thể thấy, có một đối tượng để nhận cuộc gọi ...


1
Ok, vì vậy hãy thử đọc nguồn Thông số kỹ thuật để có một số manh mối và woah. Đó là một ví dụ tuyệt vời về các vấn đề với mã ma thuật - quá nhiều mixin, kiểu suy luận và chuyển đổi ngầm định và các tham số ngầm định. Nhìn từ ngoài vào trong thật khó hiểu! Đối với các thư viện lớn như thế, dụng cụ tốt hơn có thể làm một số điều kỳ diệu ... một ngày nào đó ...
Antony Stubbs

3

Tôi thấy dễ dàng hơn khi tuân theo quy tắc ngón tay cái này: trong các không gian biểu thức xen kẽ giữa các phương thức và tham số. Trong ví dụ của bạn, (service.findAllPresentations.get.first.votes.size) must be equalTo(2)phân tích cú pháp dưới dạng (service.findAllPresentations.get.first.votes.size).must(be)(equalTo(2)). Lưu ý rằng các dấu ngoặc đơn xung quanh 2 có liên kết cao hơn các khoảng trắng. Dấu chấm cũng có tính liên kết cao hơn, vì vậy (service.findAllPresentations.get.first.votes.size) must be.equalTo(2)sẽ phân tích cú pháp như vậy (service.findAllPresentations.get.first.votes.size).must(be.equalTo(2)).

service findAllPresentations get first votes size must be equalTo 2phân tích cú pháp như service.findAllPresentations(get).first(votes).size(must).be(equalTo).2.


2

Trên thực tế, ở lần đọc thứ hai, có lẽ đây là chìa khóa:

Với các phương thức chỉ nhận một tham số duy nhất, Scala cho phép nhà phát triển thay thế. với một khoảng trắng và bỏ qua dấu ngoặc đơn

Như đã đề cập trong bài đăng trên blog: http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-6 .

Vì vậy, có lẽ đây thực sự là một "đường cú pháp" rất nghiêm ngặt, chỉ hoạt động khi bạn đang gọi một phương thức hiệu quả , trên một đối tượng, có một tham số . ví dụ

1 + 2
1.+(2)

Và không có gì khác.

Điều này sẽ giải thích các ví dụ của tôi trong câu hỏi.

Nhưng như tôi đã nói, nếu ai đó có thể chỉ ra chính xác vị trí được chỉ định trong thông số ngôn ngữ, điều này sẽ được đánh giá cao.

Được rồi, một số bạn tốt (paulp_ từ #scala) đã chỉ ra thông tin này ở đâu trong ngôn ngữ:

6.12.3: Mức độ ưu tiên và tính liên kết của các toán tử xác định nhóm các phần của một biểu thức như sau.

  • Nếu có một số hoạt động infix trong một biểu thức, thì các toán tử có mức độ ưu tiên cao hơn liên kết chặt chẽ hơn các toán tử có mức độ ưu tiên thấp hơn.
  • Nếu có các thao tác infix liên tiếp e0 op1 e1 op2. . .opn vi với các toán tử op1 ,. . . , chọn cùng một mức độ ưu tiên, thì tất cả các toán tử này phải có cùng tính liên kết. Nếu tất cả các toán tử là liên kết trái, trình tự được hiểu là (... (E0 op1 e1) op2...) Opn en. Ngược lại, nếu tất cả các toán tử là tương đối phải, thì chuỗi được hiểu là e0 op1 (e1 op2 (.. .Opn en)...).
  • Toán tử postfix luôn có mức độ ưu tiên thấp hơn toán tử infix. Ví dụ: e1 op1 e2 op2 luôn tương đương với (e1 op1 e2) op2.

Toán hạng bên phải của toán tử kết hợp bên trái có thể bao gồm một số đối số được đặt trong dấu ngoặc đơn, ví dụ: e op (e1,.., En). Biểu thức này sau đó được hiểu là e.op (e1,..., En).

Phép toán nhị phân kết hợp trái e1 op e2 được hiểu là e1.op (e2). Nếu op là quyền đối lập, thì phép toán tương tự được hiểu là {val x = e1; e2.op (x)}, trong đó x là tên mới.

Hmm - với tôi nó không khớp với những gì tôi đang thấy hoặc tôi không hiểu nó;)


hmm, để thêm vào sự nhầm lẫn, điều này cũng hợp lệ: (((((((((((((((thực)) realService findAllPresentations) realService findAllPresentations) đầu tiên) phiếu bầu)) kích thước)) phải bằng 2, nhưng không phải nếu tôi loại bỏ bất kỳ cặp dấu ngoặc nào đó ...
Antony Stubbs

2

Không có bất kỳ. Bạn có thể sẽ nhận được lời khuyên về việc liệu chức năng này có tác dụng phụ hay không. Đây là không có thật. Điều chỉnh là không sử dụng các tác dụng phụ trong phạm vi hợp lý được Scala cho phép. Trong phạm vi mà nó không thể, thì tất cả các cược sẽ tắt. Tất cả các cược. Sử dụng dấu ngoặc đơn là một phần tử của tập hợp "tất cả" và là không cần thiết. Nó không cung cấp bất kỳ giá trị nào khi tất cả các cược đã tắt.

Lời khuyên này về cơ bản là một nỗ lực nhằm vào một hệ thống hiệu ứng không thành công (không nên nhầm lẫn với: ít hữu ích hơn các hệ thống hiệu ứng khác).

Cố gắng không gây tác dụng phụ. Sau đó, chấp nhận rằng tất cả các cược đã tắt. Ẩn sau một ký hiệu cú pháp trên thực tế cho một hệ thống hiệu ứng có thể và không, chỉ gây hại.


Chà, nhưng đó là vấn đề khi bạn đang làm việc với một ngôn ngữ OO / Chức năng kết hợp phải không? Trong bất kỳ ví dụ thực tế nào bạn sẽ muốn có các chức năng hiệu ứng phụ ... Bạn có thể chỉ cho chúng tôi một số thông tin về "hệ thống hiệu ứng" không? Tôi nghĩ rằng câu trích dẫn nhiều hơn đáng chú ý là "Một hàm không có tham số có thể được khai báo mà không có dấu ngoặc đơn, trong trường hợp đó nó phải được gọi mà không có dấu ngoặc đơn. Điều này cung cấp hỗ trợ cho Nguyên tắc truy cập thống nhất, do đó người gọi không biết ký hiệu là một biến hoặc một hàm không có tham số. ”.
Antony Stubbs vào
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.