2016-12-03 19 views
6

Tôi đang viết một trình phân tích cú pháp trong Go for Go và để kiểm tra nó, tôi đã tải xuống một loạt tệp từ các dự án github.
Trong https://github.com/andlabs/ui tôi đâm sầm vào một tập tin chứa đoạn mã này:Đối số chưa được đặt tên có phải là điều trong Go không?

func moveLabel(*Button) { 
    from := movingCurrent 
    to := 0 
    if from == 0 { 
     to = 1 
    } 
    movingBoxes[from].Delete(0) 
    movingBoxes[to].Append(movingLabel, false) 
    movingCurrent = to 
} 

Nó nhầm lẫn cho tôi một chút để nhìn thấy một con trỏ đến một Button mà không có một tên như là một đối số chức năng, mà làm cho nó không thể tham khảo từ bên trong chức năng.
Tuy nhiên, nó có vẻ là cú pháp chính xác cho rằng trình biên dịch không phàn nàn.
Mục đích của các đối số chức năng chưa được đặt tên trong Go là gì?

+0

thêm chi tiết, giải thích (dựa trên spec) và liên kết cho câu trả lời. – icza

Trả lời

8

Thông số chưa đặt tên hoàn toàn hợp lệ. Các Parameter declaration từ spec:

ParameterDecl = [ IdentifierList ] [ "..." ] Type . 

Như bạn có thể thấy, IdentifierList (tên định danh hoặc tên) nằm trong dấu ngoặc vuông, có nghĩa là nó là tùy chọn. Chỉ yêu cầu Type.

Lý do là vì tên không thực sự quan trọng đối với người gọi phương thức hoặc chức năng. Điều quan trọng là các loại tham số và thứ tự của chúng. Chi tiết này được nêu chi tiết trong câu trả lời này: Getting method parameter names in Golang

Nói chung, bạn đặt tên biến và thông số để bạn có thể tham chiếu đến chúng.

Khi bạn không nêu tên gì đó, đó là vì bạn không muốn tham chiếu đến nó.

Vì vậy, câu hỏi nên là: Tại sao tôi không muốn tham chiếu đến thông số?

Ví dụ: vì tham số "có" (thông qua) nhưng bạn không cần, bạn không muốn sử dụng. Tại sao nó lại ở đó nếu tôi không cần nó?

Vì ai đó hoặc một cái gì đó mệnh lệnh để có thông số cụ thể ở đó. Ví dụ bạn muốn thực hiện một giao diện, hoặc bạn muốn chuyển một giá trị hàm có chữ ký được xác định bởi kiểu hàm được mong đợi.

Hãy xem ví dụ. Chúng ta có giao diện MyWriter sau:

type MyWriter interface { 
    Write(p []byte) error 
} 

Một đơn giản io.Writer mà chỉ trả về một lỗi, nhưng không báo cáo số byte bằng văn bản. Nếu bạn muốn cung cấp một thực hiện mà chỉ loại bỏ các dữ liệu (tương tự như ioutil.Discard), sau đó thực hiện không sử dụng (không cần phải sử dụng) đối số của nó:

type DiscardWriter struct{} 

func (DiscardWriter) Write([]byte) error { return nil } 

Và đó là tất cả: chúng tôi không' t sử dụng người nhận, chúng tôi không sử dụng đối số. Cả hai có thể không được đặt tên. Và việc triển khai thực hiện chính xác những gì nó cần.

Làm như vậy (sử dụng thông số chưa đặt tên) cũng tài liệu rằng giá trị không được sử dụng/được gọi.

Một lý do khác có thể là cung cấp khả năng tương thích về phía trước. Nếu bạn phát hành một thư viện, bạn không thể thay đổi hoặc mở rộng danh sách tham số mà không phá vỡ tính tương thích ngược (và trong Không có quá tải hàm: nếu bạn muốn 2 biến thể có các tham số khác nhau, tên của chúng phải khác nhau). Vì vậy, bạn có thể khai báo hàm hoặc phương thức đã xuất với các tham số bổ sung sớm, nhưng vì bạn chưa sử dụng chúng, bạn có thể để chúng không được đặt tên. Một ví dụ về điều này được nêu chi tiết trong câu trả lời này: Why does Go allow compilation of unused function parameters?

Một điều cần lưu ý ở đây là bạn không thể kết hợp các thông số được đặt tên và chưa đặt tên. Nếu bạn đặt tên cho một số, bạn phải đặt tên tất cả. Nếu bạn không cần tất cả, bạn có thể sử dụng blank identifier như trong ví dụ này:

Một máy chủ web đơn giản mà đáp lại với "Hello" văn bản cho tất cả các yêu cầu:

http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { 
    io.WriteString(w, "Hello") 
}) 
panic(http.ListenAndServe(":8080", nil)) 

Chức năng xử lý gửi lại "Hello" văn bản chỉ sử dụng trình ghi trả lời w, nhưng không phải cấu trúc yêu cầu, do đó, số nhận dạng trống được sử dụng làm tên của nó.

Một câu hỏi liên quan:

Why must we declare a variable name when adding a method to a struct in Golang?

Cũng phần nào liên quan, nhưng liên quan đến sử dụng/đặt tên giá trị trả về:

Return map like 'ok' in Golang on normal functions

Các vấn đề liên quan