Bagikan melalui


Fungsi

Fungsi adalah nilai yang mewakili pemetaan dari sekumpulan nilai argumen ke satu nilai. Fungsi dipanggil dengan menyediakan sekumpulan nilai input (nilai argumen), dan menghasilkan satu nilai output (nilai pengembalian).

Menulis fungsi

Fungsi ditulis menggunakan ekspresi fungsi:

ekspresi fungsi:
      (parameter-listopt)function-return-typeopt=>function-body
isi fungsi:
      expression
parameter-list:
      fixed-parameter-list
      fixed-parameter-list
,optional-parameter-list
      opsional-parameter-list
fixed-parameter-list:
      parameter
      parameter
,fixed-parameter-list
parameter:
      parameter-name parameter-typeopt
parameter-name:
      identifier
jenis parameter:
      assertion
function-return-type:
      assertion
Pernyataan:

      asnullable-primiitve-type
opsional-parameter-list:
      parameter opsional
      opsional-parameter
,opsional-parameter-list
parameter opsional:

      optionalparameter
nullable-primitve-type
      nullable
optprimitif-type

Berikut ini adalah contoh fungsi yang membutuhkan tepat dua nilai x dan y, dan menghasilkan hasil penerapan operator ke nilai tersebut + . dan adalah parameter yang merupakan bagian dari daftar parameter fungsi, dan x + y adalah isi fungsi:yx

(x, y) => x + y

Hasil dari mengevaluasi ekspresi fungsi adalah menghasilkan nilai fungsi (bukan untuk mengevaluasi isi fungsi). Sebagai konvensi dalam dokumen ini, nilai fungsi (dibandingkan dengan ekspresi fungsi) ditampilkan dengan daftar parameter tetapi dengan elipsis (...) alih-alih isi fungsi. Misalnya, setelah ekspresi fungsi di atas dievaluasi, ekspresi fungsi akan ditampilkan sebagai nilai fungsi berikut:

 (x, y) => ...

Operator berikut didefinisikan untuk nilai fungsi:

Operator Hasil
x = y Equal
x <> y Tidak sama dengan

Jenis asli nilai fungsi adalah jenis fungsi kustom (berasal dari jenis functionintrinsik ) yang mencantumkan nama parameter dan menentukan semua jenis parameter dan jenis pengembalian menjadi any. (Buka Jenis fungsi untuk detail tentang jenis fungsi.)

Memanggil fungsi

Isi fungsi fungsi dijalankan dengan memanggil nilai fungsi menggunakan invoke-expression. Memanggil nilai fungsi berarti isi fungsi dari nilai fungsi dievaluasi dan nilai dikembalikan atau kesalahan dimunculkan.

invoke-expression:
      opt daftarargumen ekspresi(primer
)
daftar argumen:
      daftar ekspresi

Setiap kali nilai fungsi dipanggil, sekumpulan nilai ditentukan sebagai daftar argumen, yang disebut argumen ke fungsi.

Daftar argumen digunakan untuk menentukan jumlah argumen tetap secara langsung sebagai daftar ekspresi. Contoh berikut mendefinisikan rekaman dengan nilai fungsi dalam bidang, lalu memanggil fungsi dari bidang rekaman lain:

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

Berikut ini berlaku saat memanggil fungsi:

  • Lingkungan yang digunakan untuk mengevaluasi isi fungsi fungsi mencakup variabel yang sesuai dengan setiap parameter, dengan nama yang sama dengan parameter . Nilai setiap parameter sesuai dengan nilai yang dibangun dari daftar argumen dari invoke-expression, seperti yang didefinisikan dalam Parameter.

  • Semua ekspresi yang sesuai dengan argumen fungsi dievaluasi sebelum isi fungsi dievaluasi.

  • Kesalahan yang dimunculkan saat mengevaluasi ekspresi dalam daftar ekspresi atau isi fungsi disebarluaskan.

  • Jumlah argumen yang dibangun dari daftar argumen harus kompatibel dengan parameter fungsi, atau kesalahan dimunculkan dengan kode "Expression.Error"alasan . Proses untuk menentukan kompatibilitas ditentukan dalam Parameter.

Parameter

Ada dua jenis parameter yang mungkin ada dalam daftar parameter:

  • Parameter yang diperlukan menunjukkan bahwa argumen yang sesuai dengan parameter harus selalu ditentukan saat fungsi dipanggil. Parameter yang diperlukan harus ditentukan terlebih dahulu dalam daftar parameter. Fungsi dalam contoh berikut mendefinisikan parameter yang x diperlukan dan y:

      [ 
          MyFunction = (x, y) => x + y, 
    
          Result1 = MyFunction(1, 1),     // 2 
          Result2 = MyFunction(2, 2)      // 4
      ] 
    
  • Parameter opsional menunjukkan bahwa argumen yang sesuai dengan parameter dapat ditentukan saat fungsi dipanggil, tetapi tidak diperlukan untuk ditentukan. Jika argumen yang sesuai dengan parameter opsional tidak ditentukan saat fungsi dipanggil, maka nilai null digunakan sebagai gantinya. Parameter opsional harus muncul setelah parameter yang diperlukan dalam daftar parameter. Fungsi dalam contoh berikut mendefinisikan parameter x tetap dan parameter yopsional :

      [ 
          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
      ] 
    

Jumlah argumen yang ditentukan ketika fungsi dipanggil harus kompatibel dengan daftar parameter. Kompatibilitas sekumpulan argumen A untuk fungsi F dihitung sebagai berikut:

  • Biarkan nilai N mewakili jumlah argumen yang A dibangun dari daftar argumen. Contohnya:

      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
    
  • Biarkan nilai Diperlukan mewakili jumlah parameter F tetap dan Opsional jumlah parameter opsional .F Contohnya:

    ()               // Required = 0, Optional = 0 
    (x)              // Required = 1, Optional = 0 
    (optional x)     // Required = 0, Optional = 1 
    (x, optional y)  // Required = 1, Optional = 1
    
  • A Argumen kompatibel dengan fungsi F jika berikut ini benar:

    • (N >= Tetap) dan (N <= (Tetap + Opsional))
    • Jenis argumen kompatibel dengan Fjenis parameter terkait
  • Jika fungsi memiliki jenis pengembalian yang dideklarasikan, maka nilai hasil isi fungsi F kompatibel dengan Fjenis pengembalian 's jika berikut ini benar:

    • Nilai yang dihasilkan dengan mengevaluasi isi fungsi dengan argumen yang disediakan untuk parameter fungsi memiliki jenis yang kompatibel dengan jenis pengembalian.
  • Jika isi fungsi menghasilkan nilai yang tidak kompatibel dengan jenis pengembalian fungsi, kesalahan dengan kode "Expression.Error" alasan dimunculkan.

Fungsi rekursif

Untuk menulis nilai fungsi yang rekursif, perlu menggunakan operator cakupan (@) untuk mereferensikan fungsi dalam cakupannya. Misalnya, rekaman berikut berisi bidang yang menentukan Factorial fungsi, dan bidang lain yang memanggilnya:

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

Demikian pula, fungsi yang saling rekursif dapat ditulis selama setiap fungsi yang perlu diakses memiliki nama. Dalam contoh berikut, bagian dari Factorial fungsi telah direfaktor menjadi fungsi kedua Factorial2 .

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

Penutupan

Fungsi dapat mengembalikan fungsi lain sebagai nilai. Fungsi ini pada gilirannya dapat bergantung pada satu atau beberapa parameter ke fungsi asli. Dalam contoh berikut, fungsi yang terkait dengan bidang MyFunction mengembalikan fungsi yang mengembalikan parameter yang ditentukan untuknya:

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

Setiap kali fungsi dipanggil, nilai fungsi baru akan dikembalikan yang mempertahankan nilai parameter sehingga ketika dipanggil, nilai parameter akan dikembalikan.

Fungsi dan lingkungan

Selain parameter, isi fungsi ekspresi fungsi dapat mereferensikan variabel yang ada di lingkungan saat fungsi diinisialisasi. Misalnya, fungsi yang ditentukan oleh bidang MyFunction mengakses bidang C rekaman Apenutup :

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

Ketika MyFunction dipanggil, ia mengakses nilai variabel C, meskipun sedang dipanggil dari lingkungan (B) yang tidak berisi variabel C.

Deklarasi yang disederhanakan

Setiap ekspresi adalah singkatan syntactic untuk mendeklarasikan fungsi yang tidak diketik mengambil parameter tunggal bernama _ (garis bawah).

setiap ekspresi:
      eachsetiap-ekspresi-isi
setiap-ekspresi-isi:
      isi fungsi

Deklarasi yang disederhanakan umumnya digunakan untuk meningkatkan keterbacaan pemanggilan fungsi dengan urutan yang lebih tinggi.

Misalnya, pasangan deklarasi berikut setara secara semantik:

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