Trang này cung cấp thông tin tổng quan về Starlark, trước đây gọi là Skylark, ngôn ngữ được dùng trong Bazel. Để xem danh sách đầy đủ các hàm và loại, hãy xem tài liệu tham khảo về API Bazel.
Để biết thêm thông tin về ngôn ngữ này, hãy xem kho lưu trữ GitHub của Starlark.
Để biết thông số kỹ thuật chính thức về cú pháp và hành vi của Starlark, hãy xem Thông số kỹ thuật ngôn ngữ Starlark.
Cú pháp
Cú pháp của Starlark được lấy cảm hứng từ Python3. Đây là cú pháp hợp lệ trong 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)
Ngữ nghĩa của Starlark có thể khác với Python, nhưng hiếm khi có sự khác biệt về hành vi, ngoại trừ các trường hợp Starlark báo lỗi. Các loại Python sau đây được hỗ trợ:
Khả năng biến đổi
Starlark ưu tiên tính bất biến. Có hai cấu trúc dữ liệu có thể thay đổi: danh sách và dicts. Các thay đổi đối với cấu trúc dữ liệu có thể thay đổi, chẳng hạn như thêm một giá trị vào danh sách hoặc xoá một mục trong từ điển, chỉ hợp lệ đối với các đối tượng được tạo trong ngữ cảnh hiện tại. Sau khi một ngữ cảnh kết thúc, các giá trị của ngữ cảnh đó sẽ trở thành không thể thay đổi.
Điều này là do các bản dựng Bazel sử dụng tính năng thực thi song song. Trong một bản dựng, mỗi tệp .bzl
và mỗi tệp BUILD
sẽ có ngữ cảnh thực thi riêng. Mỗi quy tắc cũng được phân tích trong ngữ cảnh riêng.
Hãy xem ví dụ về tệp 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 tạo var
khi foo.bzl
tải. Do đó, var
là một phần của ngữ cảnh của foo.bzl
. Khi chạy, fct()
sẽ chạy trong ngữ cảnh của foo.bzl
. Sau khi quá trình đánh giá cho foo.bzl
hoàn tất, môi trường sẽ chứa một mục nhập không thể thay đổi, var
, với giá trị [5]
.
Khi một bar.bzl
khác tải các biểu tượng từ foo.bzl
, các giá trị đã tải sẽ không thể thay đổi. Vì lý do này, mã sau đây trong bar.bzl
là không hợp lệ:
# `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
Bạn không thể thay đổi các biến toàn cục được xác định trong tệp bzl
bên ngoài tệp bzl
đã xác định các biến đó. Giống như ví dụ trên sử dụng tệp bzl
, giá trị do các quy tắc trả về là bất biến.
Sự khác biệt giữa tệp BUILD và .bzl
Các tệp BUILD
đăng ký mục tiêu thông qua việc gọi các quy tắc. Tệp .bzl
cung cấp định nghĩa cho hằng số, quy tắc, macro và hàm.
Hàm gốc và quy tắc gốc là các biểu tượng toàn cục trong tệp BUILD
. Các tệp bzl
cần tải các tệp đó bằng mô-đun native
.
Có hai quy định hạn chế về cú pháp trong tệp BUILD
: 1) khai báo hàm là bất hợp pháp và 2) không cho phép đối số *args
và **kwargs
.
Điểm khác biệt với Python
Biến toàn cục là biến không thể thay đổi.
Không được phép sử dụng câu lệnh
for
ở cấp cao nhất. Thay vào đó, hãy sử dụng các hàm đó trong hàm. Trong tệpBUILD
, bạn có thể sử dụng tính năng nắm bắt danh sách.Không được phép sử dụng câu lệnh
if
ở cấp cao nhất. Tuy nhiên, bạn có thể sử dụng biểu thứcif
:first = data[0] if len(data) > 0 else None
.Thứ tự xác định để lặp lại qua Từ điển.
Không được phép đệ quy.
Loại int chỉ giới hạn ở số nguyên có dấu 32 bit. Lỗi tràn sẽ xảy ra.
Sửa đổi một tập hợp trong quá trình lặp lại là lỗi.
Ngoại trừ các kiểm thử bằng, các toán tử so sánh
<
,<=
,>=
,>
, v.v. không được xác định trên các loại giá trị. Tóm lại:5 < 'foo'
sẽ gửi một lỗi và5 == "5"
sẽ trả về giá trị false.Trong các bộ dữ liệu, dấu phẩy ở cuối chỉ hợp lệ khi bộ dữ liệu nằm giữa dấu ngoặc đơn — khi bạn viết
(1,)
thay vì1,
.Giá trị cố định của từ điển không được có khoá trùng lặp. Ví dụ: đây là một lỗi:
{"a": 4, "b": 7, "a": 1}
.Chuỗi được biểu thị bằng dấu ngoặc kép (chẳng hạn như khi bạn gọi repr).
Chuỗi không thể lặp lại.
Các tính năng Python sau đây không được hỗ trợ:
- nối chuỗi ngầm ẩn (sử dụng toán tử
+
tường minh). - So sánh theo chuỗi (chẳng hạn như
1 < x < 5
). class
(xem hàmstruct
).import
(xem câu lệnhload
).while
,yield
.- các loại float và set.
- trình tạo và biểu thức trình tạo.
is
(hãy sử dụng==
).try
,raise
,except
,finally
(xemfail
để biết lỗi nghiêm trọng).global
,nonlocal
.- hầu hết các hàm tích hợp, hầu hết các phương thức.