2012-07-08 21 views
15

Từ đọc sách của tôi của spec:Sự khác biệt về phạm vi đóng cửa giữa các khai báo biến ngắn và các khai báo dài trong Go là gì?

Một khai báo biến ngắn ... là viết tắt của một thường xuyên biến khai với các biểu thức khởi tạo nhưng không có loại ...

http://golang.org/ref/spec

Tôi đã nghĩ rằng hai giống hệt nhau:

var f func() 
f = func() { 
    ... 
} 

f := func() { 
    ... 
} 

Nhưng có vẻ như không. Tôi đã cố gắng để quấn một chức năng tự đệ quy bên trong một chức năng bên ngoài, nhưng công trình này:

func myOuter() { 
    var f func() 

    f = func() { 
     f() 
    } 

    f() 
} 

Nhưng điều này không, nói undefined: f trong hàm nội tại.

func myOuter() { 
    f := func() { 
     f() 
    } 

    f() 
} 

Vậy sự khác biệt là gì? Có cách nào để viết điều này với tuyên bố mẫu ngắn hay tôi có phải viết nó dài tay không?

+0

Cảm ơn Kissaki, tôi rõ ràng đã dán cùng một điều hai lần do nhầm lẫn. – Joe

Trả lời

14

f := func() { /* ... */ } giống hệt với var f func() = func() { /* ... */ } (nhưng chỉ sau này được phép ở cấp gói). Trong trường hợp cụ thể của bạn, cả hai biến thể đều không hoạt động, vì câu lệnh sẽ được đánh giá từ phải sang trái. Giải pháp là - như bạn đã đề xuất - để tách tuyên bố thành hai. Một để khai báo biến này và biến khác để gán hàm đệ quy cho nó.

+1

Cảm ơn! Thứ tự hay tuyên bố không xảy ra với tôi. – Joe

+0

Ah! Bây giờ tôi phải tháo mã của tôi một lần nữa, cảm ơn vì cái nhìn sâu sắc này! –

0

Hai mẫu mã đầu tiên của bạn giống hệt nhau về mặt ngữ nghĩa trong một điều kiện: biểu thức được gán cho biến của bạn cần phải giải quyết tại thời gian biên dịch.

Điều này sẽ giống hệt nhau trong mọi trường hợp ngoại trừ khi bạn đang cố gán một biểu thức tham chiếu biến (hoặc hàm) mà bạn vừa khai báo. Vấn đề ở đây là bởi vì golang được phân tích cú pháp đúng cách, nó sẽ cố gắng gõ giải quyết biểu thức bên phải trước khi gán nó sang bên trái. Nếu bạn tham chiếu biến ở bên trái toán tử gán-assign, bạn đang tham chiếu một biến mà trình biên dịch chưa có kiến ​​thức, do đó undefined: f.

Một ví dụ khác đó sẽ mang lại kết quả tương tự:

x := x + 1 

Mặc dù đây là ít phổ biến để mọi người cố gắng vì nó là rõ ràng hơn rằng x chưa được giao.

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