Shell
zsh 有類似閉包的東西嗎?
我剛剛決定嘗試 zsh(通過 oh-my-zsh),現在正在
precmd
模擬一個兩行提示,其中包含正確提示,而不僅僅是最後一行。所以我複製了預設主題,並受到這篇文章的啟發(我也用它來學習很多東西),我做了這樣的事情(我稍後會添加顏色):
function precmd { local cwd="${(%):-[%~]}" local who_where="${(%):-%n@%m}" local git_info=${(%)$(git_prompt_info)} local right_prompt=" $git_info [$who_where]" local left_prompt="${(r:(($COLUMNS - ${#${right_prompt}})):: :)cwd}" echo "$left_prompt$right_prompt" }
它有效。但我不禁想知道:zsh 是否在每次呼叫 precmd 時都定義了所有這些變數?
我一直在搜尋與 zsh 相關的閉包、範圍和命名空間,希望將本地變數作為數據附加到 precmd,因此不需要每次都重新定義變數,但我什麼也沒找到。有什麼方法可以做我正在嘗試的事情,還是應該放棄它?
作為旁注,並且僅當它相關時,“載入函式”是什麼意思?
Zsh 沒有閉包、包或命名空間之類的東西。Zsh 缺少真正的閉包所需的一堆東西:
- 函式不是一流的。您不能將函式作為參數傳遞給其他函式,函式也不能返回其他函式。(您可以傳遞要呼叫的函式的名稱,但這與傳遞函式本身不同)。
- 你不能有嵌套函式。zsh 中的所有函式都是全域的。您必須為函式名稱添加前綴以避免衝突。請特別注意,函式將隱藏同名的外部程序。如果你有一個函式被呼叫
ls
,它將被呼叫而不是程序ls
。這可能很有用,除非您不小心這樣做。- 變數是動態範圍的,而不是像大多數現代語言那樣是靜態範圍的。即使您可以擁有嵌套函式,內部函式也不會以您通常期望的方式關閉外部函式的局部變數。你不能用它們來製作模組,就像人們在 Javascript 中所做的那樣。
- Zsh確實有匿名函式,但沒有任何這些其他東西,它們並沒有多大用處。
所以基本上,你能做的最好的就是給你所有的函式和全域變數加上前綴。
我還要指出,你應該
precmd
像這樣定義你的:% autoload -Uz add-zsh-hook % add-zsh-hook precmd my_precmd_function
add-zsh-hook
讓您可以將您的函式掛接到precmd
其中,而不會覆蓋任何其他可能也想掛接的函式precmd
。載入函式意味著什麼是一個單獨的問題。Zsh 具有自動載入功能,僅在實際呼叫函式時才從磁碟載入函式。當你這樣做時
autoload -Uz foobar
,這使得名為的函式foobar
可以呼叫。當您實際呼叫foobar
時,它會從磁碟載入定義。