Các khối ngụ ý dấu ngoặc đơn. Ví dụ: khi thấy các khối sau, bạn giả định rằng điều đó có nghĩa là -(5 + 2)
chứ không phải -5 + 2
vì 5
và 2
là một phần của một khối và -
là một phần của một khối khác.
Tuy nhiên, nếu bạn đặt dấu ngoặc đơn xung quanh mọi khối, mã sẽ khó đọc hơn nhiều. So sánh (((5) * (2)) + (3))
với 5 * 2 + 3
. Cả hai biểu thức này đều đánh giá ra cùng một kết quả (13
) nhưng biểu thức thứ hai dễ đọc hơn nhiều.
Các quy tắc về thứ tự ưu tiên của toán tử trong Blockly giúp bạn tạo mã với số lượng dấu ngoặc đơn tối thiểu để dễ đọc nhất.
Tạo đầu ra "chính xác"
Nếu bạn không cần mã được tạo phải dễ đọc, thì bạn không cần phải lo lắng về việc giảm thiểu dấu ngoặc đơn. Việc gói mọi khối là một phương pháp hay và đảm bảo rằng mã được tạo luôn được đánh giá chính xác.
Để đảm bảo tính chính xác, hãy luôn truyền Order.ATOMIC
đến các lệnh gọi valueToCode
và luôn trả về Order.NONE
từ trình tạo mã khối.
Tạo dấu ngoặc đơn tối ưu
Bạn chỉ cần chèn dấu ngoặc đơn nếu mã được tạo không chính xác nếu không có dấu ngoặc đơn. Điều này xảy ra khi mức độ ưu tiên của một toán tử trong khối bên ngoài mạnh hơn mức độ ưu tiên của một toán tử trong khối bên trong.
Ví dụ: trong các khối sau đây, có một toán tử phủ định một ngôi và một toán tử cộng. Toán tử phủ định một ngôi có mức độ ưu tiên cao hơn toán tử cộng.
Vì vậy, nếu không thêm dấu ngoặc đơn, bạn sẽ nhận được -5 + 2
và -
được đánh giá trước +
, không khớp với các khối.
Bạn có thể cho trình tạo biết thời điểm chèn dấu ngoặc đơn bằng cách cho biết mức độ mạnh của các toán tử. Nếu thấy toán tử bên ngoài mạnh hơn toán tử bên trong, thì trình biên dịch sẽ chèn dấu ngoặc đơn để bảo vệ toán tử bên trong.
valueToCode
nhận mức độ ưu tiên của toán tử bên ngoài và bộ dữ liệu trả về chỉ định mức độ ưu tiên của toán tử bên trong.
Dưới đây là ví dụ về một khối chứa hai toán tử:
import {javascriptGenerator, Order} from 'blockly/javascript';
javascriptGenerator.forBlock['negate_plus_two'] = function(block, generator) {
// valueToCode takes in the precedence of the outer operator.
const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
const code = `-${innerCode} + 2`;
// The return tuple specifies the precedence of the inner operator.
return [code, Order.ADDITION];
}
Mức độ ưu tiên của valueToCode
Khi gọi valueToCode
để tạo mã của một khối bên trong, bạn sẽ truyền cho khối đó thứ tự ưu tiên của toán tử mạnh nhất tác động lên mã của khối bên trong. Đây là toán tử mà mã của khối bên trong cần được bảo vệ.
Ví dụ: trong các khối sau, cả toán tử phủ định một ngôi và toán tử cộng đều hoạt động trên mã của khối bên trong. Toán tử phủ định một ngôi mạnh hơn, vì vậy, đó là thứ tự ưu tiên bạn nên truyền vào valueToCode
.
// The - is the strongest operator acting on the inner code.
const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
const code = `-${innerCode} + 2`;
Trả về thứ tự ưu tiên
Khi bạn trả về một mức độ ưu tiên từ trình tạo mã khối, hãy trả về mức độ ưu tiên của toán tử yếu nhất trong mã của khối. Đây là toán tử cần được bảo vệ.
Ví dụ: khối sau đây chứa cả toán tử phủ định một ngôi và toán tử cộng. Toán tử cộng yếu hơn, vì vậy, đó là mức độ ưu tiên mà bạn nên trả về từ trình tạo mã khối.
const code = `-${innerCode} + 2`;
// The + is the weakest operator in the block.
return [code, Order.ADDITION];
Enum thứ tự
Mỗi mô-đun trình tạo ngôn ngữ xác định một enum Order
bao gồm tất cả các mức độ ưu tiên cho ngôn ngữ đó.
Các mức độ ưu tiên cao hơn có giá trị sao lưu thấp hơn và các mức độ ưu tiên thấp hơn có giá trị sao lưu cao hơn. Bạn có thể coi các mức độ ưu tiên mạnh là "được xếp hạng cao hơn" về sức mạnh và các mức độ ưu tiên yếu là "được xếp hạng thấp hơn" – như thể chúng là những võ sĩ cạnh tranh.
Tại đây, bạn có thể tìm thấy các enum Order
cho tất cả ngôn ngữ tích hợp:
Mức độ ưu tiên đặc biệt
Hầu hết các mức độ ưu tiên trong enum Order
của trình tạo đều khớp với các mức độ ưu tiên do ngôn ngữ dựa trên văn bản tương ứng xác định. Tuy nhiên, có hai mức độ ưu tiên đặc biệt là Order.ATOMIC
và Order.NONE
.
Order.ATOMIC
là mức độ ưu tiên cao nhất. Phương thức này được dùng khi:
- Bạn muốn đảm bảo mã luôn được đặt trong dấu ngoặc đơn, nên bạn truyền mã đó đến
valueToCode
. - Khối của bạn không bao gồm bất kỳ toán tử nào, vì vậy, bạn sẽ trả về khối đó từ trình tạo mã khối.
Order.NONE
là mức độ ưu tiên thấp nhất. Phương thức này được dùng khi:
- Bạn muốn đảm bảo mã luôn được đặt trong dấu ngoặc đơn, nên bạn sẽ trả về mã đó từ trình tạo mã khối.
- Không có toán tử nào hoạt động trên khối bên trong, vì vậy, bạn truyền khối đó đến
valueToCode
.