Bị mắc kẹt với GNU awk 3.1.6 và nghĩ rằng tôi đã khắc phục các lỗi mảng của nó nhưng vẫn có vấn đề giống như phạm vi trong chương trình awk 600 dòng. Cần xác minh sự hiểu biết về phạm vi mảng trong awk để tìm lỗi của tôi.
Cho mã awk minh họa này ...
function foo(ga) {
ga[1] = "global result"
}
garray[1] = "global"
foo(garray)
print garray[1]
sẽ in ...
global result
Vì các mảng luôn được truyền cho các hàm bằng tham chiếu, nên tất cả các mảng luôn là toàn cục. Không có cách nào để tạo một mảng cục bộ. Điều này có đúng không? Đã không thể tìm thấy các tài liệu nói rõ ràng rằng.
Vì tôi đang gỡ lỗi và bản thân 3.1.6 đã biết các lỗi trong khu vực này, nên tôi đang cố gắng xác định nơi các lỗi của awk rời đi và tôi bắt đầu.
Bổ sung: Tại sao ga [] hoạt động bên trong hàm?
Trước hết, việc truyền mảng cho hàm foo(ga)
thực sự không cần thiết. Chỉ cần truy cập nó như garray[]
bên trong chức năng. Tuy nhiên, không có hình phạt hiệu suất có thể đo lường được khi thực hiện nó và nó giúp gỡ lỗi và báo cáo lỗi.
Trong việc sử dụng foo(ga)
, ga[]
là một từ đồng nghĩa cho mảng toàn cầu garray[]
. Thay vì là một bản sao cục bộ garray[]
, nó chỉ đơn giản là một con trỏ tới garray[]
, giống như một liên kết tượng trưng là một con trỏ tới một tệp và do đó cùng một tệp (hoặc mảng) có thể được truy cập dưới nhiều tên.
Bổ sung: Làm rõ câu trả lời của Glenn Jackman
Trong khi các mảng được tạo bên ngoài một hàm là toàn cục cho hàm và có thể được truyền cho nó hoặc chỉ được tham chiếu bên trong nó, các mảng được tạo bên trong một hàm thực sự vẫn là cục bộ của hàm và không hiển thị bên ngoài hàm. Sửa đổi ví dụ của ông Jackman minh họa điều này ...
awk '
function bar(x,y) {
split("hello world", y)
print "x[1] inside: " x[1]
print "y[1] inside: " y[1]
}
BEGIN {
x[1]="goodbye"
print "x[1] before: " x[1]
print "y[1] before: " y[1]
bar(x)
print "x[1] after: " x[1]
print "y[1] after: " y[1]
}
'
x[1] before: goodbye
y[1] before:
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after:
Lưu ý rằng chúng ta chỉ truyền x[]
mảng (thực ra, chỉ là một con trỏ tới nó) bar()
. Các y[]
mảng thậm chí không tồn tại cho đến khi chúng tôi có được bên trong hàm.
Tuy nhiên, nếu chúng ta khai báo y[]
bằng cách đưa nó vào bar()
danh sách đối số mà không gán bất cứ thứ gì cho nó bên ngoài hàm, nó sẽ hiển thị sau khi gọi bar(x,y)
...
awk '
function bar(x,y) {
split("hello world", y)
print "x[1] inside: " x[1]
print "y[1] inside: " y[1]
}
BEGIN {
x[1]="goodbye"
print "x[1] before: " x[1]
print "y[1] before: " y[1]
bar(x,y)
print "x[1] after: " x[1]
print "y[1] after: " y[1]
}
'
x[1] before: goodbye
y[1] before:
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello
Cuối cùng, nếu chúng ta tạo y[]
mảng bên ngoài hàm và chuyển nó đi bar(x,y)
, thì split()
phép gán bên trong hàm sẽ thay thế các phần tử của mảng đó ...
awk '
function bar(x,y) {
split("hello world", y)
print "x[1] inside: " x[1]
print "y[1] inside: " y[1]
}
BEGIN {
x[1]="goodbye"
y[1]="howdy"
print "x[1] before: " x[1]
print "y[1] before: " y[1]
bar(x,y)
print "x[1] after: " x[1]
print "y[1] after: " y[1]
}
'
x[1] before: goodbye
y[1] before: howdy
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello