`declare -a A` 是否在 Bash 中建立一個空數組 `A`?

`declare -a A` 是否在 Bash 中建立一個空數組 `A`?

是否在 bash 中declare -a A建立一個空數組A,或只是設定一個屬性以防A稍後分配?

考慮這段程式碼:

set -u
declare -a A
echo ${#A[*]}
echo ${A[*]}
A=()
echo ${#A[*]}
echo ${A[*]}
A=(1 2)
echo ${#A[*]}
echo ${A[*]}

預期輸出應該是多少?

在 Bash 4.3.48(1) 中,我bash: A: unbound variable在查詢 後的元素數量時得到declare。訪問所有元素時我也會遇到該錯誤。我知道 Bash 的更高版本對此有不同的處理方式。我還是想知道是否declare真的定義一個變數(為空)。

答案1

這取決於對應的變數是否已經在目前作用域(頂級也稱為全域或目前函數)中聲明過。

如果尚未在目前作用域中聲明它(請注意,在頂級作用域中,該變數可能具有宣告(並透過從環境導入它來分配),然後聲明它(在函數作用域中使其成為函數的本地函數),為其分配一個類型,但不初始化它,甚至不初始化為空列表(declare -p a顯示declare -a a,不像declare -a a=()您用 ) 聲明和/或分配它那樣a=()

如果它已經在目前作用域中聲明(例如,因為它是在全域作用域中從環境中作為標量變數匯入的),那麼declare -a a將嘗試轉變它到一個數組。

如果它以前是標量,那麼它就會變成([0]=value-of-the-variable)數組。如果它已經是一個數組,則保持不變。如果它是關聯數組,則會失敗並出現cannot convert associative to indexed array錯誤。

請注意,這declare a不會將數組或散列轉換為標量。bash無論如何都無法將哈希/數組轉換為標量。您可以使用declare +aA a強制標量(如果變數以前是目前範圍內的雜湊/數組,則會失敗並出現錯誤)。

在您的情況下,該變數可能尚未在當前作用域中聲明,因此它最終被聲明但未分配,這解釋了為什麼嘗試在set -u.

兩者之間的區別宣告分配的/變數的狀態不特定於bash。在 POSIX 中sh,您還可以export建立變數或readonly不為其賦值。

$ sh -uc 'unset -v var; readonly var; : "$var"'
sh: 1: var: parameter not set

請注意,unset取消設定和取消聲明變數。在 中bashmkshyash可以從外部範圍恢復變數。

在 中zsh,除模擬外,如果變數尚未設定或已設定但來自不同類型(標量、陣列或關聯數組),則shusing on 變數會聲明並將其設為空值。typeset

相關內容