Bahasa Starlark

Laporkan masalah Lihat sumber Per Malam · 7,2 · 7,1 · 7,0 · 6,5 · 6,4

Halaman ini adalah ringkasan tentang Starlark, sebelumnya dikenal sebagai Skylark, bahasa yang digunakan dalam Bazel. Untuk daftar lengkap fungsi dan jenisnya, lihat referensi Bazel API.

Untuk mengetahui informasi selengkapnya tentang bahasa tersebut, lihat repo GitHub Starlark.

Untuk spesifikasi otoritatif dari {i>syntax<i} Starlark dan lihat Starlark Language Specification.

Sintaksis

Sintaksis Starlark terinspirasi oleh Python3. Ini adalah sintaks yang valid di 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)

Semantik Starlark bisa berbeda dari Python, tetapi ada perbedaan jarang terjadi, kecuali untuk kasus ketika Starlark menimbulkan {i>error<i}. Python berikut jenis yang didukung:

Mutabilitas

Starlark mendukung ketetapan. Tersedia dua struktur data yang dapat berubah: daftar dan dikte. Perubahan menjadi dapat diubah struktur data, seperti menambahkan nilai ke daftar atau menghapus entri dalam hanya berlaku untuk objek yang dibuat dalam konteks saat ini. Setelah konteks selesai, nilainya menjadi tidak dapat diubah.

Hal ini karena build Bazel menggunakan eksekusi paralel. Selama proses build, setiap .bzl dan setiap file BUILD mendapatkan konteks eksekusinya sendiri. Setiap aturan juga dianalisa dalam konteksnya sendiri.

Mari kita lihat contoh dengan file 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 membuat var saat foo.bzl dimuat. var demikian menjadi bagian dari foo.bzl konteks tambahan. Saat fct() berjalan, hal ini akan dilakukan dalam konteks foo.bzl. Sesudah evaluasi untuk foo.bzl selesai, lingkungan berisi entri yang tidak dapat diubah, var, dengan nilai [5].

Saat bar.bzl lain memuat simbol dari foo.bzl, nilai yang dimuat akan tetap ada tidak dapat diubah. Oleh karena itu, kode berikut di bar.bzl bersifat ilegal:

# `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

Variabel global yang ditentukan dalam bzl file tidak dapat diubah di luar bzl file yang menentukannya. Sama seperti contoh di atas yang menggunakan file bzl, nilai yang ditampilkan oleh aturan tidak dapat diubah.

Perbedaan antara file BUILD dan .bzl

BUILD file mendaftarkan target dengan melakukan panggilan ke aturan. .bzl file menyediakan untuk konstanta, aturan, makro, dan fungsi.

Fungsi native dan aturan native adalah simbol global di BUILD. File bzl harus dimuat menggunakan modul native.

Ada dua batasan sintaksis dalam file BUILD: 1) mendeklarasikan fungsi adalah ilegal, dan 2) argumen *args dan **kwargs tidak diperbolehkan.

Perbedaan dengan Python

  • Variabel global tidak dapat diubah.

  • Pernyataan for tidak diizinkan di tingkat teratas. Menggunakannya dalam fungsi sebagai gantinya. Dalam BUILD file, Anda dapat menggunakan pemahaman daftar.

  • Pernyataan if tidak diizinkan di tingkat teratas. Namun, ekspresi if dapat digunakan: first = data[0] if len(data) > 0 else None.

  • Urutan determenistik untuk iterasi melalui Kamus.

  • Pengulangan tidak diizinkan.

  • Jenis int dibatasi hingga bilangan bulat 32-bit yang ditandatangani. Overflow akan menampilkan error.

  • Mengubah koleksi selama iterasi merupakan sebuah error.

  • Kecuali untuk pengujian kesetaraan, operator perbandingan <, <=, >=, >, dll. adalah tidak ditentukan di seluruh jenis nilai. Singkatnya: 5 < 'foo' akan menampilkan error dan 5 == "5" akan menampilkan nilai salah.

  • Pada tuple, tanda koma di akhir hanya berlaku jika tuple berada di antara tanda kurung — saat Anda menulis (1,), bukan 1,.

  • Literal kamus tidak boleh memiliki kunci duplikat. Sebagai contoh, ini adalah error: {"a": 4, "b": 7, "a": 1}.

  • String ditunjukkan dengan tanda kutip ganda (seperti ketika Anda memanggil repr).

  • String tidak dapat iterable.

Fitur Python berikut tidak didukung:

  • penyambungan string implisit (gunakan operator + eksplisit).
  • Perbandingan berantai (seperti 1 < x < 5).
  • class (lihat fungsi struct).
  • import (lihat pernyataan load).
  • while, yield.
  • jenis {i>float<i} dan {i>set<i}.
  • generator dan ekspresi generator.
  • is (sebagai gantinya, gunakan ==).
  • try, raise, except, finally (lihat fail untuk mengetahui error fatal).
  • global, nonlocal.
  • sebagian besar fungsi {i>built-in<i}, sebagian besar metode.