แชร์ผ่าน


ฟังก์ชัน

ฟังก์ชัน เป็นค่าที่แสดงการแมปจากชุดค่าอาร์กิวเมนต์ไปยังค่าเดียว ฟังก์ชันจะถูกเรียกใช้โดยมีชุดของค่าอินพุต (ค่าอาร์กิวเมนต์) และทําให้เกิดค่าเอาต์พุตเดียว (ค่าที่ส่งกลับ)

ฟังก์ชันการเขียน

ฟังก์ชันจะถูกเขียนโดยใช้ function-expression:

function-expression:
      (parameter-listopt)function-return-typeopt=>function-body
function-body:
      นิพจน์
parameter-list:
      fixed-parameter-list
      fixed-parameter-list
,optional-parameter-list
      optional-parameter-list
fixed-parameter-list:
      พารามิเตอร์
      parameter
,fixed-parameter-list
พารามิเตอร์:
      parameter-name parameter-typeopt
parameter-name:
      ตัวระบุ
parameter-type:
      การยืนยัน
function-return-type:
      การยืนยัน
ยืนยัน:

      asnullable-primiitve-type
optional-parameter-list:
      optional-parameter (พารามิเตอร์ทางเลือก)
      optional-parameter
,optional-parameter-list
optional-parameter:

      optionalพารามิเตอร์
nullable-primitve-type
      nullable
optprimitive-type

ต่อไปนี้เป็นตัวอย่างของฟังก์ชันที่จําเป็นต้องมีสองค่า x และ yและสร้างผลลัพธ์ของการใช้ตัว + ดําเนินการ กับค่าเหล่านั้น และ เป็นพารามิเตอร์ที่เป็นส่วนหนึ่งของ parameter-list ของฟังก์ชัน และ x + y คือ function-body:yx

(x, y) => x + y

ผลลัพธ์ของการประเมิน function-expression คือการสร้างค่าฟังก์ชัน (ไม่ใช้ประเมิน function-body) เนื่องจากเป็นแบบแผนในเอกสารนี้ ค่าฟังก์ชัน (ตรงกันข้ามกับนิพจน์ฟังก์ชัน) จะแสดงขึ้นพร้อมกับ parameter-list แต่มีจุดไข่ปลา (...) แทนที่จะเป็น function-body ตัวอย่างเช่น หลังจากประเมินนิพจน์ฟังก์ชันข้างต้นแล้ว จะแสดงเป็นค่าฟังก์ชันต่อไปนี้:

 (x, y) => ...

ตัวดําเนินการต่อไปนี้ถูกกําหนดไว้สําหรับค่าฟังก์ชัน:

Operator ผลลัพธ์
x = y Equal
x <> y Not equal

ค่าฟังก์ชันชนิดเนทีฟเป็นชนิดฟังก์ชันแบบกําหนดเอง (มาจากชนิดfunctionอินทรินซิก ) ที่แสดงรายชื่อพารามิเตอร์และระบุชนิดพารามิเตอร์ทั้งหมดและชนิดที่แสดงจะเป็นany (ไปที่ ชนิด ฟังก์ชันสําหรับรายละเอียดเกี่ยวกับชนิดฟังก์ชัน)

การเรียกใช้ฟังก์ชัน

function-body ของฟังก์ชันจะถูกดําเนินการโดยการเรียกใช้ค่าฟังก์ชันโดยใช้ invoke-expression การเรียกใช้ค่าฟังก์ชัน หมายความว่า function-body ของค่าฟังก์ชันจะถูกประเมิน และระบบจะแสดงค่า หรือแสดงข้อผิดพลาด

invoke-expression:
      primary-expression
(argument-listopt)
argument-list:
      expression-list

ในแต่ละครั้งที่มีการเรียกใช้ค่าฟังก์ชัน ชุดค่าจะถูกระบุเป็น argument-list ซึ่งเรียกว่า อาร์กิวเมนต์ สําหรับฟังก์ชัน

argument-list ถูกใช้เพื่อระบุจํานวนอาร์กิวเมนต์แบบคงที่เป็นรายการนิพจน์โดยตรง ตัวอย่างต่อไปนี้จะกําหนดเรกคอร์ดด้วยค่าฟังก์ชันในเขตข้อมูล จากนั้น จะเรียกใช้ฟังก์ชันจากเขตข้อมูลอื่นของเรกคอร์ดดังกล่าว:

[ 
    MyFunction = (x, y, z) => x + y + z, 
    Result1 = MyFunction(1, 2, 3)           // 6
]

รายการต่อไปนี้จะถูกระงับไว้ ขณะเรียกใช้ฟังก์ชัน:

  • สภาพแวดล้อมที่ใช้ในการประเมิน function-body ของฟังก์ชัน ประกอบด้วยตัวแปรที่สอดคล้องกับพารามิเตอร์แต่ละรายการ โดยใช้ชื่อเดียวกันกับพารามิเตอร์ ค่าของแต่ละพารามิเตอร์จะสอดคล้องกับค่าที่สร้างขึ้นจาก argument-list ของ invoke-expression ตามที่กําหนดไว้ใน พารามิเตอร์

  • นิพจน์ทั้งหมดที่สอดคล้องกับอาร์กิวเมนต์ของฟังก์ชันจะถูกประเมินก่อนทําการประเมิน function-body

  • มีข้อผิดพลาดเกิดขึ้นขณะประเมินนิพจน์ใน expression-list หรือ function-body จะถูกเผยแพร่

  • จํานวนอาร์กิวเมนต์ที่สร้างขึ้นจาก argument-list ต้องเข้ากันได้กับพารามิเตอร์ของฟังก์ชัน หรือมีข้อผิดพลาดเกิดขึ้นพร้อมรหัส "Expression.Error"เหตุผล กระบวนการสําหรับการกําหนดความเข้ากันได้จะถูกกําหนดใน พารามิเตอร์

พารามิเตอร์

พารามิเตอร์ที่อาจมีอยู่ใน parameter-list มีสองชนิด:

  • พารามิเตอร์ ที่จําเป็น ระบุว่า ต้องระบุอาร์กิวเมนต์ที่สอดคล้องกับพารามิเตอร์ทุกครั้งที่มีการเรียกใช้ฟังก์ชัน ต้องระบุพารามิเตอร์ที่จําเป็นก่อนใน parameter-list ฟังก์ชันในตัวอย่างต่อไปนี้ จะกําหนดพารามิเตอร์ x ที่จําเป็น และ y:

      [ 
          MyFunction = (x, y) => x + y, 
    
          Result1 = MyFunction(1, 1),     // 2 
          Result2 = MyFunction(2, 2)      // 4
      ] 
    
  • พารามิเตอร์ ที่เลือกได้ ระบุว่า อาจระบุอาร์กิวเมนต์ที่สอดคล้องกับพารามิเตอร์เมื่อมีการเรียกใช้ฟังก์ชัน แต่ไม่จําเป็นต้องระบุ หากไม่มีการระบุอาร์กิวเมนต์ที่สอดคล้องกับพารามิเตอร์ที่เลือกได้เมื่อมีการเรียกใช้ฟังก์ชัน ค่า null จะถูกใช้แทน พารามิเตอร์ที่เลือกได้ต้องปรากฏขึ้นหลังจากพารามิเตอร์ที่จําเป็นใดๆ ใน parameter-list ฟังก์ชันในตัวอย่างต่อไปนี้ จะกําหนดพารามิเตอร์ x แบบคงที่และพารามิเตอร์ yที่เลือกได้ :

      [ 
          MyFunction = (x, optional y) =>
                            if (y = null) x else x + y, 
          Result1 = MyFunction(1),        // 1 
          Result2 = MyFunction(1, null),  // 1 
          Result3 = MyFunction(2, 2),     // 4
      ] 
    

จํานวนอาร์กิวเมนต์ที่ระบุเมื่อมีการเรียกใช้ฟังก์ชัน จําเป็นต้องเข้ากันได้กับรายการพารามิเตอร์ ความเข้ากันได้ของชุดอาร์กิวเมนต์ A สําหรับฟังก์ชัน F จะถูกคํานวณดังนี้:

  • กําหนดให้ค่า N หมายถึงจํานวนอาร์กิวเมนต์Aที่สร้างจาก argument-list ตัวอย่างเช่น

      MyFunction()             // N = 0 
      MyFunction(1)            // N = 1 
      MyFunction(null)         // N = 1 
      MyFunction(null, 2)      // N = 2 
      MyFunction(1, 2, 3)      // N = 3 
      MyFunction(1, 2, null)   // N = 3 
      MyFunction(1, 2, {3, 4}) // N = 3
    
  • กําหนดให้ค่าที่จําเป็น หมายถึงจํานวนพารามิเตอร์คงที่ของ F และ ค่าทางเลือก จํานวนพารามิเตอร์ทางเลือกของF ตัวอย่างเช่น

    ()               // Required = 0, Optional = 0 
    (x)              // Required = 1, Optional = 0 
    (optional x)     // Required = 0, Optional = 1 
    (x, optional y)  // Required = 1, Optional = 1
    
  • Aอาร์กิวเมนต์ เข้ากันได้กับฟังก์ชัน F ถ้ารายการต่อไปนี้เป็นจริง:

    • (N >= คงที่) และ (N <= (คงที่ + ทางเลือก))
    • ชนิดอาร์กิวเมนต์เข้ากันได้กับ Fชนิดพารามิเตอร์ที่สอดคล้องกันของ
  • หากฟังก์ชันมีชนิดการแสดงผลลัพธ์ที่ประกาศ แสดงว่าค่าผลลัพธ์ของเนื้อความฟังก์ชัน F เข้ากันได้กับ Fชนิดการแสดงของ หากรายละเอียดต่อไปนี้เป็นจริง:

    • ค่าที่ให้ผลลัพธ์โดยการประเมินเนื้อความฟังก์ชันด้วยอาร์กิวเมนต์ที่ให้มาสําหรับพารามิเตอร์ฟังก์ชันจะมีชนิดที่เข้ากันได้กับชนิดผลลัพธ์
  • ถ้าเนื้อความของฟังก์ชันให้ผลลัพธ์เป็นค่าที่ไม่เข้ากันกับชนิดผลลัพธ์ของฟังก์ชัน ข้อผิดพลาดที่มีรหัส "Expression.Error" เหตุผล จะเกิดขึ้น

ฟังก์ชันแบบเรียกใช้ซ้ํา

เมื่อต้องการเขียนค่าฟังก์ชันที่มีการเรียกใช้ซ้ํา จําเป็นต้องใช้ตัวดําเนินการกําหนดขอบเขต (@) เพื่ออ้างอิงฟังก์ชันภายในขอบเขต ตัวอย่างเช่น เรกคอร์ดต่อไปนี้ประกอบด้วยเขตข้อมูลที่กําหนด Factorial ฟังก์ชัน และเขตข้อมูลอื่นที่เรียกใช้:

[ 
    Factorial = (x) => 
                if x = 0 then 1 else x * @Factorial(x - 1), 
    Result = Factorial(3)  // 6 
]

ในทํานองเดียวกัน สามารถเขียนฟังก์ชันแบบเรียกใช้ซ้ําที่มีร่วมกันได้ตราบใดที่แต่ละฟังก์ชันที่จําเป็นต้องเข้าถึงมีชื่อ ในตัวอย่างต่อไปนี้ ส่วนหนึ่งของFactorialฟังก์ชันได้รับการปรับให้เป็นฟังก์ชันที่สองFactorial2

[ 
    Factorial = (x) => if x = 0 then 1 else Factorial2(x), 
    Factorial2 = (x) => x * Factorial(x - 1), 
    Result = Factorial(3)     // 6 
]

ปิด

ฟังก์ชันสามารถแสดงฟังก์ชันอื่นเป็นค่าได้ ฟังก์ชันนี้อาจเปลี่ยนพารามิเตอร์อย่างน้อยหนึ่งตัวให้กลายเป็นฟังก์ชันดั้งเดิมได้ ในตัวอย่างต่อไปนี้ ฟังก์ชันที่เกี่ยวข้องกับเขตข้อมูล MyFunction จะแสดงฟังก์ชันที่ส่งกลับพารามิเตอร์ที่ระบุ:

[ 
    MyFunction = (x) => () => x, 
    MyFunction1 = MyFunction(1), 
    MyFunction2 = MyFunction(2), 
    Result = MyFunction1() + MyFunction2()  // 3 
]

แต่ละครั้งที่มีการเรียกใช้ฟังก์ชัน ค่าฟังก์ชันใหม่จะถูกส่งกลับ ซึ่งจะรักษาค่าของพารามิเตอร์ไว้เพื่อให้สามารถแสดงค่าพารามิเตอร์ได้เมื่อมีการเรียกใช้

ฟังก์ชันและสภาพแวดล้อม

นอกเหนือจากพารามิเตอร์ต่างๆ แล้ว function-body ของ function-expression จะสามารถอ้างอิงตัวแปรที่แสดงในสภาพแวดล้อมเมื่อมีการเตรียมใช้งานฟังก์ชัน ตัวอย่างเช่น ฟังก์ชันที่กําหนดโดยเขตข้อมูล MyFunction จะเข้าถึงเขตข้อมูล C ของเรกคอร์ด Aที่ล้อมรอบ :

[ 
A =  
    [ 
        MyFunction = () => C, 
        C = 1 
    ], 
B = A[MyFunction]()           // 1 
]

เมื่อมีการMyFunctionเรียกใช้ ระบบจะเข้าถึงค่าของตัวแปร Cแม้ว่าจะถูกเรียกใช้จากสภาพแวดล้อม (B) ที่ไม่มีตัวแปรC

ประกาศแบบประยุกต์

each-expression เป็นข้อความแบบย่อเชิงไวยากรณ์สําหรับการประกาศฟังก์ชันที่ไม่ระบุชนิด ซึ่งใช้พารามิเตอร์เดียวที่ชื่อว่า _ (ขีดล่าง)

each-expression:
      eacheach-expression-body
each-expression-body:
      function-body

ประกาศแบบประยุกต์มักใช้เพื่อปรับปรุงความสามารถในการอ่านของการเรียกใช้ฟังก์ชันในลําดับที่สูงกว่า

ตัวอย่างเช่น คู่ประกาศต่อไปนี้เทียบเท่ากันในทางความหมาย:

each _ + 1 
(_) => _ + 1  
each [A] 
(_) => _[A] 
 
Table.SelectRows( aTable, each [Weight] > 12 ) 
Table.SelectRows( aTable, (_) => _[Weight] > 12 )