語句

let 和 def 的範圍

在 Chester 中,let 和 def 用於宣告繫結,但它們在處理範圍和前向引用時有所不同。了解這些差異對於撰寫正確且高效的 Chester 程式至關重要。

let 繫結

  • 區域範圍:let 繫結僅在宣告後在當前塊中可見。
  • 不允許前向引用:你不能在宣告之前引用 let 繫結。
  • 類型推斷:如果沒有提供類型註解,編譯器會從繫結的主體推斷類型。

範例

// 正確使用 let
let x = 5;
let y = x; // 'x' 在使用前已定義
// Incorrect usage of 'let'
let y = x + 2; // Error: 'x' is not defined yet
let x = 5;

def Bindings

  • 全域範圍:def 繫結在整個塊中可見,甚至在宣告之前。
  • 允許前向引用:你可以在宣告之前引用 def 繫結。
  • 需要類型註解:如果你在宣告之前使用 def 繫結,必須提供類型註解。

範例

// 正確使用 def 並提供類型註解
def y = square(5); // 'square' 在使用前已宣告

def square(n: Int) = n * n; // 需要類型註解
// Incorrect usage of 'def' without type annotation
def y = increment(5); // 'increment' is used before its declaration

def increment(n) = n + 1; // Error: Missing type annotation for 'n'

範圍規則摘要

  • let 繫結

    • 僅在當前塊中宣告後可見。
    • 不允許前向引用。
    • 如果類型可以推斷,則類型註解是可選的。
  • def 繫結

    • 在整個塊中可見。
    • 允許前向引用。
    • 在宣告之前使用時需要類型註解。

編譯器行為

當處理一個塊時,Chester 編譯器會以不同的方式處理 let 和 def 繫結,以管理範圍和類型檢查。

處理 def 繫結

  1. 收集階段

    • 編譯器收集所有 def 繫結,記錄它們的名稱、類型註解和識別符。
    • 它追蹤前向引用以檢測在宣告之前的用法。
  2. 類型註解檢查

    • 對於沒有類型註解的前向引用 def 繫結,編譯器會報告 MissingTypeAnnotationError
  3. 上下文更新

    • 編譯器將佔位符或推斷的類型添加到上下文中,允許使用前向引用 def 繫結。

Processing let Bindings

  • Sequential Processing:
    • let bindings are processed in order of their appearance.
    • Each let binding is added to the context after its declaration.
  • No Forward References:
    • Referencing a let binding before its declaration results in an error.

Best Practices

  • Use let when you don’t need to reference the binding before its declaration.
  • 當需要前向引用或定義遞歸函數時使用 def。
  • 為了避免編譯錯誤,始終為前向引用 def 繫結提供類型註解。

通過理解這些範圍規則,可以撰寫更可預測且可維護的 Chester 程式。