Starlark 언어

문제 신고 소스 보기

이 페이지는 Bazel에서 사용되는 언어인 Starlark(이전 Skylark) 개요입니다. 함수 및 유형의 전체 목록은 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는 불변성을 선호합니다. 변경 가능한 두 가지 데이터 구조, 즉 목록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

foo.bzl가 로드될 때 Bazel이 var를 만듭니다. 따라서 varfoo.bzl 컨텍스트의 일부입니다. fct()가 실행되면 foo.bzl의 컨텍스트 내에서 실행됩니다. foo.bzl 평가가 완료되면 환경에 값이 [5]인 변경 불가능한 항목 var가 포함됩니다.

다른 bar.bzlfoo.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를 반환합니다.

  • 튜플에서 후행 쉼표는 튜플이 괄호 사이에 있을 때만 유효합니다. 1, 대신 (1,)를 작성하면 됩니다.

  • 사전 리터럴에는 키가 중복될 수 없습니다. 예를 들어 {"a": 4, "b": 7, "a": 1}입니다.

  • 문자열은 큰따옴표로 표시됩니다 (예: repr를 호출하는 경우).

  • 문자열은 반복할 수 없습니다.

다음 Python 기능은 지원되지 않습니다.

  • 암시적 문자열 연결 (명시적 + 연산자 사용)
  • 연결된 비교 (예: 1 < x < 5)
  • class (struct 함수 참고).
  • import (load 문 참고).
  • while, yield:
  • float 및 set 유형입니다.
  • 생성기 및 생성기 표현식이 포함됩니다.
  • is (대신 == 사용)
  • try, raise, except, finally (심각한 오류는 fail 참고).
  • global, nonlocal:
  • 대부분의 메서드가 포함되어 있습니다.