2014-10-30 21 views
6

Tôi đang viết hàm Go có kiểu bắt chước itertools.permutations() của Python, nhưng trả lại tất cả hoán vị cùng một lúc thay vì cho phép một lần tại một thời điểm.Golang - Hành vi đa nhiệm không mong đợi

tôi nhìn thấy hành vi bất ngờ khi cập nhật 2 biến cùng một lúc trong dòng mã sau đây:

setcopy := append([]int(nil), sorted...) 
for i := 0; i < r; i++ { 
    c := counters[r-1-i] 
    current[i], setcopy = setcopy[c], append(setcopy[:c], setcopy[c+1:]...) 
} 

tôi nhận được kết quả chính xác khi tách bản cập nhật trên:

current[i] = setcopy[c] 
setcopy = append(setcopy[:c], setcopy[c+1:]...) 

tôi chủ yếu được lấy cảm hứng từ các ví dụ PopDelete từ bài viết wiki SliceTricks. Có sự khác biệt đáng kể nào giữa điều đó và những gì tôi đang cố gắng làm không?

Nếu bạn muốn kiểm tra mã đầy đủ (bao gồm ví dụ về đầu ra bị lỗi và một số báo cáo in để gỡ lỗi), bạn có thể xem this Gist.

Trả lời

7

The Go Programming Language Specification

Assignments

Số tiền thu được chuyển nhượng trong hai giai đoạn. Đầu tiên, các toán hạng của chỉ mục các biểu thức và con trỏ indirections (bao gồm cả con trỏ tiềm ẩn các số trong bộ chọn) ở bên trái và các biểu thức trên bên phải đều được đánh giá theo thứ tự thông thường. Thứ hai, các bài tập được thực hiện theo thứ tự từ trái sang phải.

Operands

Phép toán biểu thị các giá trị cơ bản trong một biểu thức. Toán hạng có thể là là một số nhận dạng không có nghĩa đen, có thể là một chữ cái có nghĩa là hằng số, biến hoặc hàm, một biểu thức phương thức sinh hàm hoặc biểu thức được lồng dấu.

Order of evaluation

Khi đánh giá các toán hạng của một biểu thức, chuyển nhượng, hoặc trả lại tuyên bố, tất cả các chức năng cuộc gọi, các cuộc gọi phương pháp, và truyền thông hoạt động được đánh giá trong trái sang phải theo thứ tự từ vựng.

Ví dụ, trong việc chuyển nhượng (chức năng địa phương) các cuộc gọi

y[f()], ok = g(h(), i()+x[j()], <-c), k() 

chức năng và truyền thông xảy ra theo thứ tự f(), h(), i(), j(), < - c, g() và k(). Tuy nhiên, thứ tự của những sự kiện đó so với việc đánh giá và lập chỉ mục của x và đánh giá y không được chỉ định.

Appending to and copying slices

Nếu năng lực của s là không đủ lớn để phù hợp với những giá trị bổ sung, append phân bổ một mảng cơ bản đủ lớn mới phù hợp cả các yếu tố lát hiện có và những giá trị bổ sung. Nếu không, nối thêm sử dụng lại mảng cơ bản.

Một mảng cơ bản mới đang được phân bổ chưa?

Việc chuyển nhượng tuyên bố

current[i], setcopy = setcopy[c], append(setcopy[:c], setcopy[c+1:]...) 

dường như là tương đương với

a := append(setcopy[:c], setcopy[c+1:]...) 
x := setcopy[c] 
y := a 
current[i], setcopy = x, y 

nhưng thứ tự của các sự kiện chức năng cuộc gọi so với đánh giá của toán hạng khác không được xác định (Order of evaluation).

+0

Tôi không nghĩ vậy, vì 'append' được sử dụng trong nhiệm vụ thực sự làm giảm kích thước của slice/xóa một phần tử (và như vậy, một mảng cơ bản mới sẽ không cần thiết). – Redy

+1

Không thể giải thích tại sao, nhưng đầu ra là giống như nếu 'append' chạy đầu tiên: http://play.golang.org/p/ZQ-4cMyNTJ – twotwotwo

+0

Nó trông giống như bạn đang hứa trái-to- đúng thứ tự eval - nếu không có ai đến với một lý do chính đáng ở đây, tôi sẽ nhấn golang-nut với điều này, có vẻ thực sự kỳ quặc. – twotwotwo

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