本頁面是 Starlark 的總覽,這個 API 舊稱 Skylark,也是 Bazel 中使用的語言。如需完整的函式與類型清單,請參閱 Bazel API 參考資料。
如要進一步瞭解該語言,請參閱 Starlark 的 GitHub 存放區。
如需 Starlark 語法和行為的權威性規範,請參閱 Starlark 語言規格。
語法
Starlark 語法是由 Python3 提供。這是 Starlark 中的有效語法:
def fizz_buzz(n):
"""Print Fizz Buzz numbers from 1 to n."""
for i in range(1, n + 1):
s = ""
if i % 3 == 0:
s += "Fizz"
if i % 5 == 0:
s += "Buzz"
print(s if s else i)
fizz_buzz(20)
Starlark 的語意可能與 Python 不同,但其行為差異並不大,除非 Starlark 引發了錯誤。以下是支援的 Python 類型:
多樣性
Starlark 喜歡改變不可變的內容。有兩種可變動的資料結構:lists 和 dicts。對可變動的資料結構所做的變更 (例如將值附加至清單或刪除字典中的項目) 僅適用於在目前結構定義中建立的物件。背景資訊結束後,其值就無法變更。
這是因為 Bazel 建構作業使用平行執行。在建構期間,每個 .bzl
檔案和每個 BUILD
檔案都會取得專屬的執行結構定義。每項規則也都會經過分析。
以 foo.bzl
檔案為例:
# `foo.bzl`
var = [] # declare a list
def fct(): # declare a function
var.append(5) # append a value to the list
fct() # execute the fct function
Bazel 會在 foo.bzl
載入時建立 var
。var
是 foo.bzl
結構定義的一部分。執行 fct()
時,會在 foo.bzl
環境內執行。完成 foo.bzl
的評估後,環境會包含不可變更的項目 var
,值為 [5]
。
當另一個 bar.bzl
從 foo.bzl
載入符號時,載入的值無法變更。基於這個原因,bar.bzl
中的下列代碼並不適當:
# `bar.bzl`
load(":foo.bzl", "var", "fct") # loads `var`, and `fct` from `./foo.bzl`
var.append(6) # runtime error, the list stored in var is frozen
fct() # runtime error, fct() attempts to modify a frozen list
定義定義 bzl
檔案的全域變數時,無法在 bzl
檔案以外的位置變更。就像上面使用 bzl
檔案的範例一樣,規則傳回的值無法變更。
BUILD 與 .bzl 檔案之間的差異
BUILD
個檔案會透過呼叫規則來註冊目標。.bzl
檔案提供常數、規則、巨集和函式的定義。
原生函式和原生規則是 BUILD
檔案中的全域符號。bzl
檔案必須使用native
模組載入。
BUILD
檔案有兩個語法限制:1) 宣告函式違法,2) 不允許使用 *args
和 **kwargs
引數。
與 Python 的差異
全域變數無法變更。
無法在頂層使用
for
陳述式。請改用函式。在BUILD
檔案中,您可以使用清單理解機制。無法在頂層使用
if
陳述式。不過,您可以使用if
運算式:first = data[0] if len(data) > 0 else None
。透過詞數進行疊代的決定順序。
不得重複,
Int 類型的上限是 32 位元的正負號整數。溢位會發生錯誤。
在疊代期間修改集合時發生錯誤。
除了相等測試以外,未在值類型定義比較運算子
<
、<=
、>=
、>
等。簡而言之,5 < 'foo'
會傳回錯誤,5 == "5"
則會傳回 false。以 Tupers 來說,只有在元組介於括號之間時,才會使用結尾的逗號;也就是說,當您撰寫
(1,)
而非1,
時。字典文字不得包含重複的鍵。例如,這是
{"a": 4, "b": 7, "a": 1}
。字串會以雙引號表示 (例如 當您呼叫 repr 時)。
字串無法復原。
系統不支援下列 Python 功能: