เอกสารนี้เป็นข้อมูลอ้างอิงเอกสาร API แบบรวมสำหรับ Common Expression Language (CEL) โดยจะแสดงรายการมาโคร โอเปอเรเตอร์ และฟังก์ชันมาตรฐานทั้งหมด พร้อมระบุลายเซ็น ลักษณะการทำงาน และสถานะการรองรับในสแต็ก CEL อย่างเป็นทางการ
ดูรายละเอียดเพิ่มเติมเกี่ยวกับลักษณะการทำงานและข้อกำหนดของภาษาได้ที่คำจำกัดความของภาษา CEL
เวอร์ชัน Stack
เอกสารอ้างอิงนี้อิงตามสแต็ก CEL เวอร์ชันต่อไปนี้
- CEL Go:
v0.29.2(และใหม่กว่า) - CEL C++:
v0.15.0 - CEL Java:
v0.13.1 - CEL Python:
v0.1.3 - CEL C: ภาพรวมการพัฒนา (ยังไม่ได้เผยแพร่)
มิเรอร์ GitHub
การใช้งาน CEL อย่างเป็นทางการจะมิเรอร์ใน GitHub ภายใต้cel-expr
องค์กร
1. มาโครหลัก
มาโครเหล่านี้เป็นมาโครในตัวที่จะขยายในเวลาคอมไพล์
| มาโคร | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
has(container.field) |
ทดสอบว่ามีฟิลด์ในข้อความหรือคีย์ในแผนที่หรือไม่ ลายเซ็น: has(container.field) -> boolตัวอย่าง: has(request.auth.claims.email) |
✓ | ✓ | ✓ | ✓ | ✓ |
list.all(var, predicate) |
ทดสอบว่าองค์ประกอบทั้งหมดในลิสต์เป็นไปตามเพรดิเคตหรือไม่ ลายเซ็น: list.all(var, predicate) -> boolตัวอย่าง: [1, 2, 3].all(x, x > 0) // true |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.exists(var, predicate) |
ทดสอบว่าองค์ประกอบอย่างน้อย 1 รายการในลิสต์ตรงตามเพรดิเคตหรือไม่ ลายเซ็น: list.exists(var, predicate) -> boolตัวอย่าง: [1, 2, 3].exists(x, x > 2) // true |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.exists_one(var, predicate) |
ทดสอบว่ามีองค์ประกอบเพียง 1 รายการในรายการที่ตรงตามเพรดิเคตหรือไม่ ลายเซ็น: list.exists_one(var, predicate) -> boolตัวอย่าง: [1, 2, 3].exists_one(x, x == 2) // true |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.filter(var, predicate) |
กรององค์ประกอบของรายการตามเพรดิเคต ลายเซ็น: list.filter(var, predicate) -> listตัวอย่าง: [1, 2, 3].filter(x, x > 1) // [2, 3] |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.map(var, transform) |
เปลี่ยนรูปแบบแต่ละองค์ประกอบของลิสต์โดยใช้นิพจน์ ลายเซ็น: list.map(var, transform) -> listตัวอย่าง: [1, 2, 3].map(x, x * 2) // [2, 4, 6] |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.map(var, filter, transform) |
เปลี่ยนรูปแบบองค์ประกอบของรายการที่ตรงตามตัวกรอง ลายเซ็น: list.map(var, filter, transform) -> listตัวอย่าง: [1, 2, 3].map(x, x > 1, x * 2) // [4, 6] |
✓ | ✓ | ✓ | ✓ | ✓¹ |
¹ รองรับในรันไทม์ C เนื่องจากคอมไพเลอร์โฮสต์จะขยายแมโครเป็นความเข้าใจในระหว่างการคอมไพล์
2. โอเปอเรเตอร์หลัก
| โอเปอเรเตอร์ | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
เลขคณิต (+, -, *, /, %) |
การดำเนินการทางคณิตศาสตร์มาตรฐาน การปฏิเสธ (-x) และเอกลักษณ์ (+x) การต่อรายการ (list + list) รองรับใน Go, C++, Java และ Pythonลายเซ็น: T + T -> TT - T -> TT * T -> TT / T -> TT % T -> T-T -> T+T -> Tlist + list -> listตัวอย่าง: 1 + 2 * 3 // 7[1] + [2] // [1, 2] |
✓ | ✓ | ✓ | ✓ | ✓² |
การเปรียบเทียบ (==, !=, <, <=, >, >=) |
การเปรียบเทียบมาตรฐาน การเปรียบเทียบตัวเลขเป็นแบบไม่เหมือนกัน (เช่น 1 == 1.0)ลายเซ็น: T == T -> boolT != T -> boolT < T -> boolT <= T -> boolT > T -> boolT >= T -> boolตัวอย่าง: x < 42.01 == 1.0 // true |
✓ | ✓ | ✓ | ✓ | ✓ |
เชิงตรรกะ (!, &&, ||, ? :) |
Logical NOT, AND, OR และ Ternary Conditional และ/หรือใช้การประเมินแบบลัด ลายเซ็น: !bool -> boolbool && bool -> boolbool || bool -> boolbool ? T : T -> Tตัวอย่าง: x > 0 ? "positive" : "non-positive" |
✓ | ✓ | ✓ | ✓ | ✓ |
การจัดทำดัชนี ([]) |
เข้าถึงองค์ประกอบของลิสต์ตามดัชนี หรือค้นหาคีย์ในแมป ลายเซ็น: list[int] -> Tmap[K] -> Vตัวอย่าง: tags[0]users['john'] |
✓ | ✓ | ✓ | ✓ | ✓ |
การเป็นสมาชิก (in) |
ตรวจสอบว่าองค์ประกอบอยู่ในลิสต์หรือคีย์อยู่ในแมป ลายเซ็น: T in list -> boolK in map -> boolตัวอย่าง: 'admin' in roles |
✓ | ✓ | ✓ | ✓ | ✓ |
² รันไทม์ C ไม่รองรับการเชื่อมโยงรายการ (list + list) แม้ว่าจะรองรับตัวดำเนินการทางคณิตศาสตร์อื่นๆ
3. ฟังก์ชันหลัก
ฟังก์ชันทั่วไปและฟังก์ชันสตริง
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
size |
แสดงขนาดของสตริง (อักขระ) ไบต์ รายการ หรือแมป ลายเซ็น: size(T) -> int (โดยที่ T คือ string, bytes, list หรือ map)<br /><br />**Examples:**<br />size("hello") // 5` |
✓ | ✓ | ✓ | ✓ | ✓ |
contains |
แสดงว่าสตริงมีสตริงย่อยหรือไม่ ลายเซ็น: string.contains(string) -> boolตัวอย่าง: "hello".contains("ell") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
startsWith |
แสดงว่าสตริงขึ้นต้นด้วยคำนำหน้าหรือไม่ ลายเซ็น: string.startsWith(string) -> boolตัวอย่าง: "hello".startsWith("he") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
endsWith |
แสดงว่าสตริงลงท้ายด้วยคำต่อท้ายหรือไม่ ลายเซ็น: string.endsWith(string) -> boolตัวอย่าง: "hello".endsWith("lo") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
matches |
แสดงผลว่าสตริงตรงกับนิพจน์ทั่วไป RE2 หรือไม่ ลายเซ็น: string.matches(string) -> boolตัวอย่าง: "123".matches(r"^\d+$") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
ฟังก์ชันตัวเลือกวันที่และเวลา
ฟังก์ชันเหล่านี้จะดึงคอมโพเนนต์จาก google.protobuf.Timestamp หรือ
google.protobuf.Duration
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
getFullYear |
แสดงปีเป็นตัวเลข 4 หลัก รูปแบบ timestamp.getFullYear([tz]) -> intตัวอย่าง timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMonth |
แสดงเดือน (0-11) ลายเซ็น: timestamp.getMonth([tz]) -> intตัวอย่าง: timestamp("2026-07-23T00:00:00Z").getMonth() // 6 |
✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfMonth |
แสดงผลวันของเดือน (1-31) รูปแบบ timestamp.getDayOfMonth([tz]) -> intตัวอย่าง timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23 |
✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfWeek |
แสดงวันในสัปดาห์ (0 = วันอาทิตย์) ลายเซ็น: timestamp.getDayOfWeek([tz]) -> intตัวอย่าง: timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4 |
✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfYear |
แสดงวันในปี (0-365) รูปแบบ timestamp.getDayOfYear([tz]) -> intตัวอย่าง timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203 |
✓ | ✓ | ✓ | ✓ | ✗ |
getHours |
แสดงผลชั่วโมง (0-23) ลายเซ็น: timestamp.getHours([tz]) -> intduration.getHours() -> intตัวอย่าง: duration("1h30m").getHours() // 1 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMinutes |
แสดงผลนาที (0-59) ลายเซ็น: timestamp.getMinutes([tz]) -> intduration.getMinutes() -> intตัวอย่าง: duration("1h30m").getMinutes() // 30 |
✓ | ✓ | ✓ | ✓ | ✗ |
getSeconds |
แสดงผลวินาที (0-59) รูปแบบลายเซ็น: timestamp.getSeconds([tz]) -> intduration.getSeconds() -> intตัวอย่าง: duration("1h30m45s").getSeconds() // 45 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMilliseconds |
แสดงผลมิลลิวินาที (0-999) ลายเซ็น: timestamp.getMilliseconds([tz]) -> intduration.getMilliseconds() -> intตัวอย่าง: duration("1.5s").getMilliseconds() // 500 |
✓ | ✓ | ✓ | ✓ | ✗ |
การแปลงประเภท
| ประเภทเป้าหมาย | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
bool |
แปลงเป็นบูลีน ลายเซ็น: bool(bool) -> boolbool(string) -> boolตัวอย่าง: bool("true") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
bytes |
แปลงเป็นไบต์ ลายเซ็น: bytes(bytes) -> bytesbytes(string) -> bytesตัวอย่าง: bytes("hello") // b"hello" |
✓ | ✓ | ✓ | ✓ | ✓ |
double |
แปลงเป็นจำนวนทศนิยมแบบความแม่นยำสองเท่า ลายเซ็น: double(double) -> doubledouble(int) -> doubledouble(uint) -> doubledouble(string) -> doubleตัวอย่าง: double(1) // 1.0 |
✓ | ✓ | ✓ | ✓ | ✓ |
duration |
แปลงเป็นระยะเวลา ลายเซ็น: duration(duration) -> durationduration(string) -> durationตัวอย่าง: duration("1.5s") // 1.5s duration |
✓ | ✓ | ✓ | ✓ | ✓ |
int |
แปลงเป็นจำนวนเต็มแบบมีเครื่องหมาย 64 บิต ลายเซ็น: int(int) -> intint(uint) -> intint(double) -> int (ปัดเป็น 0)int(string) -> intint(timestamp) -> int (วินาทีตั้งแต่ Epoch)ตัวอย่าง: int(1.5) // 1 |
✓ | ✓ | ✓ | ✓ | ✓ |
string |
แปลงเป็นสตริง ลายเซ็น: string(T) -> string (รองรับ bool, int, uint, double, bytes, timestamp, duration)<br /><br />**Examples:**<br />string(1.5) // "1.5"` |
✓ | ✓ | ✓ | ✓ | ✓ |
timestamp |
แปลงเป็น Timestamp รูปแบบ: timestamp(timestamp) -> timestamptimestamp(string) -> timestamp (RFC3339)ตัวอย่าง: timestamp("2026-07-23T00:00:00Z") |
✓ | ✓ | ✓ | ✓ | ✓ |
uint |
แปลงเป็นจำนวนเต็มแบบไม่มีเครื่องหมาย 64 บิต ลายเซ็น: uint(uint) -> uintuint(int) -> uintuint(double) -> uintuint(string) -> uintตัวอย่าง: uint(1) // 1u |
✓ | ✓ | ✓ | ✓ | ✓ |
dyn |
ส่งค่าไปยังประเภทแบบไดนามิกเพื่อตรวจสอบประเภท ลายเซ็น: dyn(T) -> dynตัวอย่าง: dyn([1, "two"]) |
✓ | ✓ | ✓ | ✓ | ✗ |
type |
แสดงผลประเภทของค่า ลายเซ็น: type(T) -> typeตัวอย่าง: type(1) // int |
✓ | ✓ | ✓ | ✓ | ✗ |
4. ส่วนขยาย (ไลบรารี)
ไลบรารีการเชื่อมโยง
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
cel.bind |
เชื่อมโยงตัวแปรภายในเพื่อหลีกเลี่ยงการประเมินที่ซ้ำกัน ลายเซ็น: cel.bind(varName, initExpr, resultExpr) -> Tตัวอย่าง: cel.bind(x, a + b, x * x) |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.Bindings()ไปยังcel.NewEnv() - C++: เพิ่ม
BindingsCompilerLibrary()ไปยังCompilerBuilder(ระบบจะจัดการรันไทม์โดยอัตโนมัติ) - Java: เพิ่ม
CelExtensions.bindings()ไปยังCelCompilerและบิลเดอร์CelRuntime - Python: นำเข้า
cel_expr_python.ext.ext_bindingsและใช้ExtBindings()ในcel.NewEnv(extensions=[...])
ไลบรารีโปรแกรมเปลี่ยนไฟล์
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
base64.encode |
เข้ารหัสไบต์เป็นสตริง Base64 ลายเซ็น: base64.encode(bytes) -> stringตัวอย่าง: base64.encode(b"hello") // "aGVsbG8=" |
✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
base64.decode |
ถอดรหัสสตริง Base64 เป็นไบต์ แสดงข้อผิดพลาดเมื่อป้อนข้อมูลที่ไม่ถูกต้อง ลายเซ็น: base64.decode(string) -> bytesตัวอย่าง: base64.decode("aGVsbG8=") // b"hello" |
✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
json.encode |
แปลงค่า CEL เป็นสตริง JSON ลายเซ็น: json.encode(dyn) -> stringตัวอย่าง: json.encode([1, 2]) // "[1,2]" |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.Encoders()ไปยังcel.NewEnv() - C++:
- ผู้เรียบเรียง: เพิ่ม
EncodersCompilerLibrary()ลงในCompilerBuilder - รันไทม์: โทรหา
RegisterEncodersFunctions()ในวันที่FunctionRegistry
- ผู้เรียบเรียง: เพิ่ม
- Java: เพิ่ม
CelExtensions.encoders()ไปยังCelCompilerและบิลเดอร์CelRuntime - Python: นำเข้า
cel_expr_python.ext.ext_encodersและใช้ExtEncoders()ในcel.NewEnv(extensions=[...])
คลังคณิตศาสตร์
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
math.greatest |
แสดงผลอาร์กิวเมนต์ตัวเลข (หรือรายการตัวเลข) ที่มากที่สุด ลายเซ็น: math.greatest(arg, ...) -> Tตัวอย่าง: math.greatest(1, 3, 2) // 3 |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.least |
แสดงผลอาร์กิวเมนต์ที่เป็นตัวเลขที่น้อยที่สุด (หรือรายการตัวเลข) ลายเซ็น: math.least(arg, ...) -> Tตัวอย่าง: math.least([1, 3, 2]) // 1 |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.abs |
ค่าสัมบูรณ์ ลายเซ็น: math.abs(T) -> T (รองรับ int, uint, double)<br /><br />**Examples:**<br />math.abs(-1) // 1` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sqrt |
รากที่สอง ลายเซ็น: math.sqrt(T) -> double (รองรับ int, uint, double)<br /><br />**Examples:**<br />math.sqrt(9) // 3.0` |
✓ (v0.25.1) | ✓ (v0.12.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
math.bitAnd |
บิตแอนด์ ลายเซ็น: math.bitAnd(T, T) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitAnd(5, 3) // 1` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitOr |
Bitwise OR ลายเซ็น: math.bitOr(T, T) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitOr(5, 3) // 7` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitXor |
บิตไวส์ XOR ลายเซ็น: math.bitXor(T, T) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitXor(5, 3) // 6` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitNot |
บิตวายน์ NOT ลายเซ็น: math.bitNot(T) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitNot(1) // -2` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftLeft |
เลื่อนบิตไปทางซ้าย ลายเซ็น: math.bitShiftLeft(T, int) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitShiftLeft(1, 2) // 4` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftRight |
เลื่อนบิตไปทางขวา ลายเซ็น: math.bitShiftRight(T, int) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitShiftRight(4, 2) // 1` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.ceil |
การปัดเศษขึ้น ลายเซ็น: math.ceil(double) -> doubleตัวอย่าง: math.ceil(1.2) // 2.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.floor |
การปัดเศษลง ลายเซ็น: math.floor(double) -> doubleตัวอย่าง: math.floor(1.8) // 1.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.round |
การปัดเศษเป็นจำนวนเต็มที่ใกล้ที่สุด ลายเซ็น: math.round(double) -> doubleตัวอย่าง: math.round(1.5) // 2.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.trunc |
การปัดเศษแบบตัดทิ้ง (เข้าหา 0) ลายเซ็น: math.trunc(double) -> doubleตัวอย่าง: math.trunc(-1.8) // -1.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isInf |
ตรวจสอบว่าค่า Double เป็นบวกหรือลบอนันต์ ลายเซ็น: math.isInf(double) -> boolตัวอย่าง: math.isInf(1.0/0.0) // true |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isNaN |
ตรวจสอบว่า double เป็น NaN หรือไม่ ลายเซ็น: math.isNaN(double) -> boolตัวอย่าง: math.isNaN(0.0/0.0) // true |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isFinite |
ตรวจสอบว่า Double เป็นค่าที่สิ้นสุดหรือไม่ ลายเซ็น: math.isFinite(double) -> boolตัวอย่าง: math.isFinite(1.2) // true |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sign |
แสดงเครื่องหมายของค่า (-1, 0 หรือ 1) ลายเซ็น: math.sign(T) -> T (รองรับ int, uint, double)<br /><br />**Examples:**<br />math.sign(-42) // -1` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.Math()ไปยังcel.NewEnv() - C++:
- ผู้เรียบเรียง: เพิ่ม
MathCompilerLibrary()ลงในCompilerBuilder - รันไทม์: โทรหา
RegisterMathExtensionFunctions()ในวันที่FunctionRegistry
- ผู้เรียบเรียง: เพิ่ม
- Java: เพิ่ม
CelExtensions.math()ไปยังCelCompilerและCelRuntimeบิลเดอร์ - Python: นำเข้า
cel_expr_python.ext.ext_mathและใช้ExtMath()ในcel.NewEnv(extensions=[...])
คลัง Protos
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
proto.getExt |
รับฟิลด์ส่วนขยาย proto2 หรือค่าเริ่มต้นหากไม่ได้ตั้งค่า ลายเซ็น: proto.getExt(msg, extName) -> Tตัวอย่าง: proto.getExt(msg, google.api.expr.test.int32_ext) |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
proto.hasExt |
ตรวจสอบว่าได้ตั้งค่าฟิลด์ส่วนขยาย proto2 หรือไม่ ลายเซ็น: proto.hasExt(msg, extName) -> boolตัวอย่าง: proto.hasExt(msg, google.api.expr.test.int32_ext) |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.Protos()ไปยังcel.NewEnv() - C++: เพิ่ม
ProtoExtCompilerLibrary()ลงในCompilerBuilder(ระบบจะจัดการรันไทม์โดยอัตโนมัติ) - Java: เพิ่ม
CelExtensions.protos()ไปยังCelCompilerและCelRuntimeบิลเดอร์ - Python: นำเข้า
cel_expr_python.ext.ext_protoและใช้ExtProto()ในcel.NewEnv(extensions=[...])
คลังรายการ
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
distinct |
แสดงผลองค์ประกอบที่ไม่ซ้ำกัน ลายเซ็น: list.distinct() -> listตัวอย่าง: [1, 2, 2].distinct() // [1, 2] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
flatten |
ทำให้รายการที่ซ้อนกันแบนราบ ลายเซ็น: list.flatten([depth]) -> listตัวอย่าง: [[1], [2, 3]].flatten() // [1, 2, 3] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.7.1) | ✓ (v0.1.1) | ✗ |
lists.range |
แสดงรายการจำนวนเต็ม [0, ..., n-1]ลายเซ็น: lists.range(int) -> list(int)ตัวอย่าง: lists.range(3) // [0, 1, 2] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
reverse |
กลับรายการ ลายเซ็น: list.reverse() -> listตัวอย่าง: [1, 2].reverse() // [2, 1] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
slice |
รายการย่อยของการคืนสินค้า (รวมจุดเริ่มต้น ไม่รวมจุดสิ้นสุด) ลายเซ็น: list.slice(start, end) -> listตัวอย่าง: [1, 2, 3].slice(1, 3) // [2, 3] |
✓ (v0.17.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sort |
จัดเรียงรายการองค์ประกอบที่เปรียบเทียบได้ ลายเซ็น: list.sort() -> listตัวอย่าง: [3, 1, 2].sort() // [1, 2, 3] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sortBy |
จัดเรียงรายการตามคีย์ที่ประเมินจากนิพจน์ ลายเซ็น: list.sortBy(var, expr) -> listตัวอย่าง: [{"val": 2}, {"val": 1}].sortBy(x, x.val) // [{"val": 1}, {"val": 2}] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
first |
แสดงผลองค์ประกอบแรกเป็นองค์ประกอบที่ไม่บังคับ ต้องใช้ส่วนขยายที่ไม่บังคับ ลายเซ็น: list.first() -> optionalตัวอย่าง: [1, 2].first() // optional(1) |
✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
last |
แสดงผลองค์ประกอบสุดท้ายเป็นค่าที่ไม่บังคับ ต้องใช้ส่วนขยายที่ไม่บังคับ ลายเซ็น: list.last() -> optionalตัวอย่าง: [1, 2].last() // optional(2) |
✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.Lists()ไปยังcel.NewEnv() - C++:
- ผู้เรียบเรียง: เพิ่ม
ListsCompilerLibrary()ลงในCompilerBuilder - รันไทม์: โทร
RegisterListsFunctions()ในวันที่FunctionRegistryและRegisterListsMacros()ในวันที่MacroRegistry
- ผู้เรียบเรียง: เพิ่ม
- Java: เพิ่ม
CelExtensions.lists()ไปยังCelCompilerและCelRuntimeบิลเดอร์ - Python: เปิดใช้ผ่าน
cel.EnvConfigโดยเพิ่มlistsลงในextensionsรายการ
คลังชุด
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
sets.contains |
ตรวจสอบว่า list1 มีองค์ประกอบทั้งหมดของ list2 หรือไม่ ลายเซ็น: sets.contains(list1, list2) -> boolตัวอย่าง: sets.contains([1, 2], [1]) // true |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.equivalent |
ตรวจสอบว่าลิสต์เทียบเท่ากับชุดหรือไม่ (มีองค์ประกอบที่ไม่ซ้ำกันเหมือนกัน) ลายเซ็น: sets.equivalent(list1, list2) -> boolตัวอย่าง: sets.equivalent([1, 2], [2, 1, 1]) // true |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.intersects |
ตรวจสอบว่ารายการแชร์องค์ประกอบอย่างน้อย 1 รายการหรือไม่ ลายเซ็น: sets.intersects(list1, list2) -> boolตัวอย่าง: sets.intersects([1, 2], [2, 3]) // true |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.Sets()ไปยังcel.NewEnv() - C++:
- ผู้เรียบเรียง: เพิ่ม
SetsCompilerLibrary()ลงในCompilerBuilder - รันไทม์: โทรหา
RegisterSetsFunctions()ในวันที่FunctionRegistry
- ผู้เรียบเรียง: เพิ่ม
- Java: เพิ่ม
CelExtensions.sets()ไปยังCelCompilerและCelRuntimeบิลเดอร์ - Python: เปิดใช้ผ่าน
cel.EnvConfigโดยเพิ่มsetsลงในextensionsรายการ
คลังสตริง
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
charAt |
แสดงอักขระที่ดัชนี ลายเซ็น: string.charAt(int) -> stringตัวอย่าง: "hello".charAt(1) // "e" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
indexOf |
แสดงดัชนีของสตริงย่อยที่เกิดขึ้นครั้งแรก หรือ -1 ลายเซ็น: string.indexOf(substr, [start]) -> intตัวอย่าง: "hello".indexOf("l") // 2 |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
lastIndexOf |
แสดงดัชนีของการเกิดสตริงย่อยครั้งสุดท้าย หรือ -1 ลายเซ็น: string.lastIndexOf(substr, [end]) -> intตัวอย่าง: "hello".lastIndexOf("l") // 3 |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
join |
ต่อสตริง ลายเซ็น: list(string).join([separator]) -> stringตัวอย่าง: ["a", "b"].join("-") // "a-b" |
✓ (v0.10.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
split |
แยกสตริงตามตัวคั่น ลายเซ็น: string.split(separator, [limit]) -> list(string)ตัวอย่าง: "a-b".split("-") // ["a", "b"] |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
substring |
ส่งคืนสตริงย่อย (รวมจุดเริ่มต้น ไม่รวมจุดสิ้นสุด) ลายเซ็น: string.substring(start, [end]) -> stringตัวอย่าง: "hello".substring(1, 3) // "el" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
trim |
ตัดช่องว่าง Unicode ลายเซ็น: string.trim() -> stringตัวอย่าง: " hello ".trim() // "hello" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
replace |
แทนที่ค่าเก่าด้วยค่าใหม่ รูปแบบ: string.replace(old, new, [limit]) -> stringตัวอย่าง: "hello".replace("l", "w") // "hewwo" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
reverse |
กลับจุดโค้ด Unicode ลายเซ็น: string.reverse() -> stringตัวอย่าง: "abc".reverse() // "cba" |
✓ (v0.18.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
lowerAscii |
แปลงอักขระ ASCII เป็นตัวพิมพ์เล็ก ลายเซ็น: string.lowerAscii() -> stringตัวอย่าง: "Hello".lowerAscii() // "hello" |
✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
upperAscii |
แปลงอักขระ ASCII เป็นตัวพิมพ์ใหญ่ ลายเซ็น: string.upperAscii() -> stringตัวอย่าง: "Hello".upperAscii() // "HELLO" |
✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
quote |
หลีกเลี่ยงสตริงเพื่อการพิมพ์ที่ปลอดภัย ลายเซ็น: strings.quote(string) -> stringตัวอย่าง: strings.quote("a\tb") // "\"a\\tb\"" |
✓ (v0.14.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.Strings()ไปยังcel.NewEnv() - C++:
- ผู้เรียบเรียง: เพิ่ม
StringsCompilerLibrary()ลงในCompilerBuilder - รันไทม์: โทรหา
RegisterStringsFunctions()ในวันที่FunctionRegistry
- ผู้เรียบเรียง: เพิ่ม
- Java: เพิ่ม
CelExtensions.strings()ไปยังCelCompilerและCelRuntimeบิลเดอร์ - Python: นำเข้า
cel_expr_python.ext.ext_stringsและใช้ExtStrings()ในcel.NewEnv(extensions=[...])
คลังนิพจน์ทั่วไป
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
regex.replace |
แทนที่รายการที่ตรงกันด้วยสตริงการแทนที่ (รองรับการอ้างอิงย้อนกลับ) รูปแบบ: regex.replace(target, pat, repl, [limit]) -> stringตัวอย่าง: regex.replace("123-456", r"(\d+)-(\d+)", r"\2-\1") // "456-123" |
✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
regex.extract |
แสดงการจับคู่แรกของรูปแบบ (ต้องมีแคปเจอร์กรุ๊ป 1 กลุ่ม) ลายเซ็น: regex.extract(target, pat) -> optional(string)ตัวอย่าง: regex.extract("a123b", r"(\d+)") // optional("123") |
✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
regex.extractAll |
แสดงผลการจับคู่ทั้งหมดของรูปแบบ (ต้องมีแคปเจอร์กรุ๊ป 1 กลุ่ม) ลายเซ็น: regex.extractAll(target, pat) -> list(string)ตัวอย่าง: regex.extractAll("a1b2", r"(\d+)") // ["1", "2"] |
✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.Regex()ไปยังcel.NewEnv() - C++:
- ผู้เรียบเรียง: เพิ่ม
RegexExtCompilerLibrary()ลงในCompilerBuilder - รันไทม์: โทรหา
RegisterRegexExtensionFunctions()ในวันที่FunctionRegistry
- ผู้เรียบเรียง: เพิ่ม
- Java: เพิ่ม
CelExtensions.regex()ไปยังCelCompilerและCelRuntimeบิลเดอร์ - Python: เปิดใช้ผ่าน
cel.EnvConfigโดยเพิ่มregexและoptionalลงใน รายการextensions
การทำความเข้าใจตัวแปร 2 ตัว
| มาโคร | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
all |
การลัดวงจร AND ตรรกะเหนือคีย์/ดัชนีและค่า ลายเซ็น: list.all(i, v, pred) -> boolmap.all(k, v, pred) -> boolตัวอย่าง: [1, 2].all(i, v, v > 0) // true |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
exists |
การลัดวงจรตรรกะ OR เหนือคีย์/ดัชนีและค่า ลายเซ็น: list.exists(i, v, pred) -> boolmap.exists(k, v, pred) -> boolตัวอย่าง: [1, 2].exists(i, v, v == 2) // true |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
existsOne |
ตรวจสอบว่ามีคู่ที่ตรงตามเพรดิเคตเพียงคู่เดียว ลายเซ็น: list.existsOne(i, v, pred) -> boolmap.existsOne(k, v, pred) -> boolตัวอย่าง: [1, 2].existsOne(i, v, v == 2) // true |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformList |
เปลี่ยน/กรองรายการ/แมปเป็นรายการ ลายเซ็น: list.transformList(i, v, [filter], transform) -> listmap.transformList(k, v, [filter], transform) -> listตัวอย่าง: [1, 2].transformList(i, v, v * 2) // [2, 4] |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMap |
เปลี่ยนค่าของรายการ/แผนที่เป็นแผนที่ (คีย์ยังคงเหมือนเดิม) ลายเซ็น: list.transformMap(i, v, [filter], transform) -> mapmap.transformMap(k, v, [filter], transform) -> mapตัวอย่าง: [1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4} |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMapEntry |
เปลี่ยนเป็นแผนที่ ลายเซ็น: list.transformMapEntry(i, v, [filter], transform_entry) -> mapmap.transformMapEntry(k, v, [filter], transform_entry) -> mapตัวอย่าง: [1, 2].transformMapEntry(i, v, {string(v): v * 2}) // {"1": 2, "2": 4} |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.TwoVarComprehensions()ไปยังcel.NewEnv() - C++:
- ผู้เรียบเรียง: เพิ่ม
ComprehensionsV2CompilerLibrary()ลงในCompilerBuilder - รันไทม์: โทร
RegisterComprehensionsV2Functions()ในวันที่FunctionRegistryและRegisterComprehensionsV2Macros()ในวันที่MacroRegistry
- ผู้เรียบเรียง: เพิ่ม
- Java: เพิ่ม
CelExtensions.comprehensions()ไปยังCelCompilerและCelRuntimeBuilders - Python: เปิดใช้ผ่าน
cel.EnvConfigโดยเพิ่มtwo-var-comprehensionsลงใน รายการextensions
คลังประเภทเนทีฟ
| ฟีเจอร์ | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
| โครงสร้างข้อมูลดั้งเดิม | การลงทะเบียนและสร้างอินสแตนซ์ของประเภทดั้งเดิมของโฮสต์ (โครงสร้าง Go / POJO ของ Java) ใน CEL ตัวอย่าง: Account{id: 123} (สร้างอินสแตนซ์ POJO ของ Java ใน CEL) |
✓ (v0.13.0) | ✗ | ✓ (v0.13.0) | ✗ | ✗ |
วิธีเปิดใช้
- ไปที่: ส่ง
ext.NativeTypes(...)(ระบุประเภทการสะท้อน) ไปยังcel.NewEnv() - C++: ไม่รองรับ
- Java: เพิ่ม
CelExtensions.nativeTypes()(ระบุคลาส Java) ลงในเครื่องมือสร้างCelCompilerและCelRuntime - Python: ไม่รองรับ
คลังเครือข่าย
ไลบรารีเครือข่ายมีฟังก์ชันสำหรับการแยกวิเคราะห์ ตรวจสอบ และจัดการ ที่อยู่ IP และบล็อก CIDR
| ฟังก์ชัน | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
ip |
แยกวิเคราะห์สตริงเป็นที่อยู่ IP หรือแยก IP จาก CIDR ลายเซ็น: ip(string) -> IPCIDR.ip() -> IPตัวอย่าง: ip("192.168.0.1")cidr("192.168.0.0/24").ip() |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isIP |
ตรวจสอบว่าสตริงเป็นที่อยู่ IP ที่ถูกต้องหรือไม่ ลายเซ็น: isIP(string) -> boolตัวอย่าง: isIP("192.168.0.1") // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
ip.isCanonical |
ตรวจสอบว่าสตริงที่อยู่ IP อยู่ในรูปแบบ Canonical หรือไม่ ลายเซ็น: ip.isCanonical(string) -> boolตัวอย่าง: ip.isCanonical("192.168.0.1") // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
cidr |
แยกวิเคราะห์สตริงเป็นบล็อก CIDR ลายเซ็น: cidr(string) -> CIDRตัวอย่าง: cidr("192.168.0.0/24") |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isCIDR |
ตรวจสอบว่าสตริงเป็นบล็อก CIDR ที่ถูกต้องหรือไม่ ลายเซ็น: isCIDR(string) -> boolตัวอย่าง: isCIDR("192.168.0.0/24") // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsIP |
ตรวจสอบว่าบล็อก CIDR มีที่อยู่ IP หรือไม่ ลายเซ็น: CIDR.containsIP(IP) -> boolCIDR.containsIP(string) -> boolตัวอย่าง: cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsCIDR |
ตรวจสอบว่าบล็อก CIDR มีบล็อก CIDR อื่นหรือไม่ ลายเซ็น: CIDR.containsCIDR(CIDR) -> boolCIDR.containsCIDR(string) -> boolตัวอย่าง: cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
family |
แสดงตระกูล IP (4 สำหรับ IPv4, 6 สำหรับ IPv6) ลายเซ็น: IP.family() -> intตัวอย่าง: ip("192.168.0.1").family() // 4 |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isGlobalUnicast |
ตรวจสอบว่า IP เป็นที่อยู่แบบ Unicast ทั่วโลกหรือไม่ ลายเซ็น: IP.isGlobalUnicast() -> boolตัวอย่าง: ip("192.168.0.1").isGlobalUnicast() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalMulticast |
ตรวจสอบว่า IP เป็นที่อยู่มัลติคาสต์ลิงก์ภายในหรือไม่ ลายเซ็น: IP.isLinkLocalMulticast() -> boolตัวอย่าง: ip("224.0.0.1").isLinkLocalMulticast() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalUnicast |
ตรวจสอบว่า IP เป็นที่อยู่แบบ Unicast ที่ลิงก์ภายในหรือไม่ ลายเซ็น: IP.isLinkLocalUnicast() -> boolตัวอย่าง: ip("169.254.0.1").isLinkLocalUnicast() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLoopback |
ตรวจสอบว่า IP เป็นที่อยู่ Loopback หรือไม่ ลายเซ็น: IP.isLoopback() -> boolตัวอย่าง: ip("127.0.0.1").isLoopback() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isMask |
ตรวจสอบว่า CIDR เป็นซับเน็ตมาสก์ที่ถูกต้องหรือไม่ รูปแบบ: CIDR.isMask() -> boolตัวอย่าง: cidr("255.255.255.0/24").isMask() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isUnspecified |
ตรวจสอบว่า IP เป็นที่อยู่ที่ไม่ได้ระบุหรือไม่ (เช่น 0.0.0.0)ลายเซ็น: IP.isUnspecified() -> boolตัวอย่าง: ip("0.0.0.0").isUnspecified() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
masked |
แสดงผลบล็อก CIDR ที่มาสก์ ลายเซ็น: CIDR.masked() -> CIDRตัวอย่าง: cidr("192.168.0.1/24").masked() // 192.168.0.0/24 |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
prefixLength |
แสดงความยาวคำนำหน้าของบล็อก CIDR ลายเซ็น: CIDR.prefixLength() -> intตัวอย่าง: cidr("192.168.0.0/24").prefixLength() // 24 |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
string |
แปลง IP หรือ CIDR เป็นสตริง ลายเซ็น: string(IP) -> stringstring(CIDR) -> stringตัวอย่าง: string(ip("192.168.0.1")) // "192.168.0.1" |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
วิธีเปิดใช้
- ไป: ส่ง
ext.Network()ไปยังcel.NewEnv() - C++: ไม่รองรับ
- Java: ไม่รองรับ
- Python: ไม่รองรับ
5. ฟีเจอร์ขั้นสูง
สรุปเกี่ยวกับฟีเจอร์ขั้นสูง
| ฟีเจอร์ | คำอธิบาย | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
| การประเมินบางส่วน | ประเมินด้วยอินพุตที่ขาดหายไป โดยจะแสดงผลเป็นค่าที่ไม่รู้จักหรือนิพจน์ที่ลดความซับซ้อนแล้ว | ✓³ | ✓⁴ | ✓⁴ | ✗ | ✗ |
| การประเมินแบบไม่พร้อมกัน | การดำเนินการฟังก์ชันส่วนขยายพร้อมกันแบบไม่บล็อก | ✓⁵ | ✗ | ✓⁶ | ✗ | ✗ |
| โปรแกรมตรวจสอบ AST | การวิเคราะห์แบบคงที่จะตรวจสอบ AST ที่ตรวจสอบแล้วหลังจากตรวจสอบประเภท | ✓ | ✓ | ✓ | ✗ | ✗ |
| เครื่องมือเพิ่มประสิทธิภาพ AST | การเขียน AST ใหม่ (การพับค่าคงที่ การแทรกอินไลน์ CSE) เพื่อปรับปรุงประสิทธิภาพ | ✓ | ✓ | ✓ | ✗ | ✗ |
| CEL Policy Compiler | คอมไพล์โครงสร้างนโยบายที่ใช้ YAML เป็น AST ของ CEL มาตรฐาน | ✓ | ✓ | ✓ | ✗ | ✗ |
³ Go รองรับการสร้าง Residual AST (AST ที่ตัดแต่งแล้ว) ⁴ C++ และ Java รองรับ
การแสดงผล UnknownSet / CelUnknownSet ที่รันไทม์ แต่ไม่ได้เปิดเผย API สาธารณะ
สำหรับการสร้าง AST ที่เหลือ ⁵ Go ใช้ AsyncBinding / AsyncOp ที่ส่งคืน
แชแนล ⁶ Java ใช้ CelAsyncRuntime ซึ่งแสดงผล ListenableFuture
การประเมินบางส่วน (ไม่ทราบ)
การประเมินบางส่วนช่วยให้ประเมินนิพจน์ได้เมื่อทราบเฉพาะชุดย่อยของตัวแปรอินพุต (อาร์กิวเมนต์) การประเมินจะสร้างผลลัพธ์ที่ระบุสิ่งที่ขาดหายไปหรือนิพจน์ที่ง่ายขึ้นแทนที่จะล้มเหลว
- ไป: รองรับอย่างเต็มที่ อนุญาตให้กำหนด
PartialActivationด้วยรูปแบบของแอตทริบิวต์ที่ไม่รู้จัก การประเมินจะแสดงผลค่าtypes.UnknownGo รองรับการสร้าง AST ที่เหลือ (Env.ResidualAst) ซึ่งเป็น AST ที่ตัดทอนและ ลดความซับซ้อนซึ่งมีเฉพาะส่วนของนิพจน์ที่ประเมินค่าไม่ได้ - C++: รองรับค่า
Unknownรูปแบบแอตทริบิวต์ที่ไม่รู้จักจะ กำหนดค่าผ่านActivation::set_unknown_attribute_patternsการประเมิน จะแสดงผลUnknownSetขณะนี้ API สาธารณะยังไม่แสดงการสร้าง AST ที่เหลือ - Java: รองรับการประเมินบางส่วนผ่าน
PartialVarspassed toProgram.eval()การประเมินจะแสดงผลCelUnknownSetขณะนี้ Public API ยังไม่แสดงการสร้าง AST ที่เหลือ - Python / C: ไม่รองรับโดยตรง
การประเมินแบบไม่พร้อมกัน
การประเมินแบบไม่พร้อมกันช่วยให้นิพจน์ CEL เรียกฟังก์ชันที่ดำเนินการแบบไม่พร้อมกัน (เช่น การเรียก RPC หรือการค้นหาฐานข้อมูล) และบล็อกการประเมินจนกว่าผลลัพธ์จะพร้อมใช้งาน โดยไม่บล็อกเธรดการดำเนินการหลัก
- Go: รองรับการโอเวอร์โหลดฟังก์ชันแบบอะซิงโครนัสผ่าน
AsyncBindingและAsyncOpฟังก์ชันแบบไม่พร้อมกันจะแสดงผลแชแนล Go (<-chan ref.Val) และ อินเทอร์พรีเตอร์จะจัดการการดำเนินการพร้อมกันและการซิงโครไนซ์ - Java: รองรับการประเมินแบบอะซิงโครนัสผ่าน
CelAsyncRuntimeและAsyncProgramโดยใช้ListenableFutureเพื่อแสดงค่าที่รอดำเนินการและ ขับเคลื่อนการประเมินให้เสร็จสมบูรณ์โดยอัตโนมัติเมื่อฟิวเจอร์ได้รับการแก้ไข - C++ / Python / C: ไม่รองรับในตัว
โปรแกรมตรวจสอบ AST
เครื่องมือตรวจสอบจะทำการวิเคราะห์แบบคงที่ใน AST ที่ตรวจสอบแล้วหลังจากตรวจสอบประเภทเพื่อ บังคับใช้ข้อจํากัดเฉพาะโดเมนก่อนที่จะมีการเรียกใช้โปรแกรม
- Go: รองรับอินเทอร์เฟซ
ASTValidatorเครื่องมือตรวจสอบ Canonical ได้แก่cel.validator.duration,cel.validator.timestamp,cel.validator.matches(นิพจน์ทั่วไป),cel.validator.homogeneous_literalsและcel.validator.comprehension_nesting_limit - C++: รองรับ
cel::Validatorการตรวจสอบ Canonical ประกอบด้วยAstDepthValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,MatchesValidatorและTimestampLiteralValidator - Java: รองรับ
CelValidatorและCelAstValidatorเครื่องมือตรวจสอบ Canonical ได้แก่AstDepthLimitValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,RegexLiteralValidatorและTimestampLiteralValidator - Python / C: ไม่มีการสนับสนุนโดยตรง
เครื่องมือเพิ่มประสิทธิภาพ AST
ตัวเพิ่มประสิทธิภาพจะเขียน AST ใหม่เพื่อปรับปรุงประสิทธิภาพการดำเนินการ ตัวเพิ่มประสิทธิภาพแบ่งออกเป็น 2 หมวดหมู่ ได้แก่ ตัวเพิ่มประสิทธิภาพแบบคงที่และตัวเพิ่มประสิทธิภาพรันไทม์ C++, Java และ Go รองรับการเพิ่มประสิทธิภาพรันไทม์ นอกจากนี้ CEL Java และ Go ยังรองรับเครื่องมือเพิ่มประสิทธิภาพแบบคงที่ด้วย การเพิ่มประสิทธิภาพทั่วไป ได้แก่ การพับค่าคงที่ (การประเมินนิพจน์ย่อยล่วงหน้า ด้วยอินพุตค่าคงที่) และการกำจัดนิพจน์ย่อยที่ซ้ำกัน (CSE)
- Go: รองรับการพับ AST ระหว่างการคอมไพล์/วางแผน
- C++: รองรับการพับค่าคงที่ผ่านส่วนขยาย
cel::extensions::EnableConstantFoldingในเวลาวางแผน - Java: รองรับอินเทอร์เฟซ
CelOptimizerตัวเพิ่มประสิทธิภาพ Canonical ได้แก่ConstantFoldingOptimizer(ซึ่งสามารถพับกิ่งก้านแบบลัดวงจรได้โดย จำลองการประเมินบางส่วน),InliningOptimizerและSubexpressionOptimizer(CSE) - Python / C: ไม่มีการสนับสนุนโดยตรง
เครื่องมือคอมไพล์นโยบาย CEL
นโยบาย CEL เป็นรูปแบบที่อิงตาม YAML สำหรับการเขียนนิพจน์ CEL หลายรายการ ร่วมกับตัวแปร บล็อกการจับคู่ เอาต์พุตแบบมีเงื่อนไข และกฎที่ซ้อนกัน โดยออกแบบมาสำหรับเครื่องมือนโยบายที่ซับซ้อน (เช่น การควบคุมการยอมรับของ Kubernetes) ซึ่งนิพจน์ CEL เดียวจะอ่านไม่ได้
คอมไพเลอร์นโยบายจะคอมไพล์นโยบาย YAML เหล่านี้เป็น AST ของ CEL มาตรฐานรายการเดียว ซึ่งหมายความว่านโยบายเหล่านี้จะเข้ากันได้กับรันไทม์ CEL มาตรฐานอย่างสมบูรณ์และจะรับประกัน ประสิทธิภาพและความปลอดภัยทั้งหมด
- ไปที่: รองรับผ่าน
third_party/cel/go/policy - C++: รองรับผ่าน
third_party/cel/cpp/policy - Java: รองรับผ่าน
third_party/java/cel/policy - Python / C: ไม่รองรับโดยตรง