Buradaki temel sorun, dizileri tasarlayan / uygulayan bash geliştiricilerinin gerçekten pooch'u vidalamasıdır. Bunun ${array}sadece kısa el olduğuna karar verdiler ${array[0]}, bu kötü bir hataydı. Özellikle bunun bir ${array[0]}anlamı olmadığını düşündüğünüzde ve dizi türü ilişkiliyse boş dizeyi değerlendirdiğinde.
Bir dizi atamak, değerin array=(value1 ... valueN)sözdizimine sahip olduğu formu alır [subscript]=string, böylece doğrudan dizideki belirli bir dizine bir değer atar. Bu, sayısal olarak indekslenmiş ve karma indekslenmiş iki tür dizi olabilmesini sağlar (bash ilişkisinde ilişkilendirilebilir diziler olarak adlandırılır). Ayrıca, sayısal olarak dizinlenmiş seyrek diziler oluşturabilmenizi sağlar. Parçayı bırakmak [subscript]=sayısal sıralı bir dizi için kısa eldir, sıra sıra 0'dan başlayarak ve atama deyimindeki her yeni değerle birlikte artar.
Bu nedenle, ${array}için değerlendirmelidir tüm dizi, endeksler ve tüm. Atama ifadesinin tersini değerlendirmelidir. Herhangi bir üçüncü yıl CS büyük bilmeli. Bu durumda, bu kod tam olarak beklediğiniz gibi çalışır:
declare -A foo bar
foo=${bar}
Daha sonra, işlevlere değerlere göre diziler iletmek ve bir diziyi diğerine atamak, kabuk sözdiziminin geri kalanı belirlediği gibi çalışır. Ancak bunu doğru yapmadıkları için, atama operatörü =diziler için çalışmaz ve diziler, echo ${array}her şeyi çiğnemek için kod olmadan işlevlere veya alt kabuklara veya genel olarak ( ) değere göre geçirilemez .
Dolayısıyla, eğer doğru bir şekilde yapılmış olsaydı, aşağıdaki örnek, dizideki dizilerin kullanışlılığının nasıl daha iyi olabileceğini gösterecektir:
simple=(first=one second=2 third=3)
echo ${simple}
elde edilen çıktı şu şekilde olmalıdır:
(first=one second=2 third=3)
Daha sonra, diziler atama işlecini kullanabilir ve işlevlere ve hatta diğer kabuk komut dosyalarına değere göre geçirilebilir. Bir dosyaya çıktı vererek kolayca saklanır ve bir dosyadan bir betiğe kolayca yüklenir.
declare -A foo
read foo <file
Ne yazık ki, başka türlü üstün bir bash geliştirme ekibi tarafından hayal kırıklığına uğradık.
Bu nedenle, bir diziyi bir işleve geçirmek için gerçekten tek bir seçenek vardır ve bu nameref özelliğini kullanmaktır:
function funky() {
local -n ARR
ARR=$1
echo "indexes: ${!ARR[@]}"
echo "values: ${ARR[@]}"
}
declare -A HASH
HASH=([foo]=bar [zoom]=fast)
funky HASH # notice that I'm just passing the word 'HASH' to the function
aşağıdaki çıktı ile sonuçlanacaktır:
indexes: foo zoom
values: bar fast
Bu referans olarak geçtiği için işlevdeki diziye de atayabilirsiniz. Evet, başvurulan dizinin genel bir kapsamı olmalıdır, ancak bunun kabuk komut dosyası olduğu düşünülürse çok büyük bir anlaşma olmamalıdır. Bir işleve ilişkisel veya seyrek dizine alınmış bir diziyi değere göre geçirmek için, tüm dizinleri ve değerleri bağımsız değişken listesine (büyük bir dizi ise çok yararlı değildir) aşağıdaki gibi tek dizeler olarak atmak gerekir:
funky "${!array[*]}" "${array[*]}"
ve sonra diziyi yeniden birleştirmek için işlevin içine bir grup kod yazmak.