Tanda tangan

File tanda tangan berisi informasi tentang tanda tangan publik dari satu set elemen program F#, seperti jenis, namespace layanan, dan modul. Dapat digunakan untuk menentukan aksesibilitas elemen program ini.

Keterangan

Untuk setiap file kode F#, Anda dapat memiliki file tanda tangan, yaitu file yang memiliki nama yang sama dengan file kode tetapi dengan ekstensi .fsi dan bukan .fs. File tanda tangan juga dapat ditambahkan ke baris perintah kompilasi jika Anda menggunakan baris perintah secara langsung. Untuk membedakan antara file kode dan file tanda tangan, file kode terkadang disebut sebagai file implementasi. Dalam sebuah proyek, file tanda tangan harus mendahului file kode terkait.

File tanda tangan menjelaskan namespace layanan, modul, jenis, dan anggota dalam file implementasi yang sesuai. Gunakan informasi dalam file tanda tangan untuk menentukan bagian kode mana dalam file implementasi yang sesuai yang dapat diakses dari kode di luar file implementasi, dan bagian mana yang merupakan internal untuk file implementasi. Namespace layanan, modul, dan jenis yang termasuk dalam file tanda tangan harus merupakan subset dari namespace layanan, modul, dan jenis yang termasuk dalam file implementasi. Dengan beberapa pengecualian yang dicatat nantinya dalam topik ini, elemen bahasa yang tidak tercantum dalam file tanda tangan dianggap privat pada file implementasi. Jika tidak ada file tanda tangan yang ditemukan di baris proyek atau perintah, aksesibilitas default akan digunakan.

Untuk informasi selengkapnya tentang aksesibilitas default, lihat Access Control.

Dalam file tanda tangan, jangan mengulangi definisi jenis dan implementasi setiap metode atau fungsi. Sebagai gantinya, gunakan tanda tangan untuk setiap metode dan fungsi, yang bertindak sebagai spesifikasi lengkap fungsionalitas yang diimplementasikan oleh modul atau fragmen namespace layanan. Sintaks untuk tanda tangan jenis sama dengan sintaks yang digunakan dalam deklarasi metode abstrak di antarmuka dan kelas abstrak, dan juga ditunjukkan oleh IntelliSense dan oleh interpreter F# fsi.exe saat menampilkan input yang dikompilasi dengan benar.

Jika tidak ada informasi yang cukup dalam tanda tangan jenis untuk menunjukkan apakah suatu jenis disegel, atau merupakan jenis antarmuka atau tidak, Anda harus menambahkan atribut yang menunjukkan sifat jenis ke penyusun. Atribut yang Anda gunakan untuk tujuan ini dijelaskan dalam tabel berikut.

Atribut Deskripsi
[<Sealed>] Untuk jenis yang tidak memiliki anggota abstrak, atau yang tidak boleh diperpanjang.
[<Interface>] Untuk jenis yang merupakan antarmuka.

Penyusun menghasilkan kesalahan jika atribut tidak konsisten antara tanda tangan dan deklarasi dalam file implementasi.

Gunakan kata kunci val untuk membuat tanda tangan untuk nilai atau nilai fungsi. Kata kunci type memperkenalkan tanda tangan jenis.

Anda dapat membuat file tanda tangan dengan menggunakan opsi penyusun --sig. Umumnya, Anda tidak menulis file .fsi secara manual. Sebagai gantinya, Anda membuat file .fsi dengan menggunakan penyusun, menambahkannya ke proyek jika ada, dan mengeditnya dengan menghapus metode dan fungsi yang tidak ingin Anda akses.

Ada beberapa aturan untuk jenis tanda tangan:

  • Jenis singkatan dalam file implementasi tidak boleh cocok dengan jenis tanpa singkatan dalam file tanda tangan.

  • Catatan dan gabungan yang didiskriminasi harus mengekspos semua atau tidak satu pun dari bidang dan konstruktornya, dan urutan dalam tanda tangan harus sesuai dengan urutan dalam file implementasi. Kelas dapat mengungkapkan beberapa, semua, atau tidak satu pun bidang dan metodenya dalam tanda tangan.

  • Kelas dan struktur yang memiliki konstruktor harus mengekspos deklarasi kelas dasar mereka (deklarasi inherits). Juga, kelas dan struktur yang memiliki konstruktor harus mengekspos semua metode abstrak dan deklarasi antarmukanya.

  • Jenis antarmuka harus mengungkapkan semua metode dan antarmukanya.

Aturan untuk tanda tangan nilai adalah sebagai berikut:

  • Pengubah untuk aksesibilitas (public, internal, dan sebagainya) dan pengubah inline dan mutable dalam tanda tangan harus cocok dengan yang ada dalam implementasi.

  • Jumlah parameter jenis generik (baik yang disimpulkan secara implisit atau dideklarasikan secara eksplisit) harus cocok, dan jenis serta batasan jenis dalam parameter jenis generik harus cocok.

  • Jika atribut Literal digunakan, atribut tersebut harus muncul dalam tanda tangan dan implementasi, dan nilai harfiah yang sama harus digunakan untuk keduanya.

  • Pola parameter (juga dikenal sebagai aritas) pada tanda tangan dan implementasi harus konsisten.

  • Jika nama parameter dalam file tanda tangan berbeda dari file implementasi yang sesuai, nama dalam file tanda tangan akan digunakan sebagai gantinya. Hal ini dapat menyebabkan masalah saat penelusuran kesalahan atau pembuatan profil. Jika Anda ingin diberi tahu tentang ketidakcocokan tersebut, aktifkan peringatan 3218 di file proyek Anda atau saat memanggil penyusun (lihat --warnon di bawah Opsi Penyusun).

Contoh kode berikut menunjukkan contoh file tanda tangan yang memiliki namespace layanan, modul, nilai fungsi, dan jenis tanda tangan bersama dengan atribut yang sesuai. Kode ini juga menunjukkan file implementasi yang sesuai.

// Module1.fsi

namespace Library1
  module Module1 =
    val function1 : int -> int
    type Type1 =
        new : unit -> Type1
        member method1 : unit -> unit
        member method2 : unit -> unit

    [<Sealed>]
    type Type2 =
        new : unit -> Type2
        member method1 : unit -> unit
        member method2 : unit -> unit

    [<Interface>]
    type InterfaceType1 =
        abstract member method1 : int -> int
        abstract member method2 : string -> unit

Kode berikut menunjukkan file implementasi.

namespace Library1

module Module1 =

    let function1 x = x + 1


    type Type1() =
        member type1.method1() =
            printfn "type1.method1"
        member type1.method2() =
            printfn "type1.method2"


    [<Sealed>]
    type Type2() =
        member type2.method1() =
            printfn "type2.method1"
        member type2.method2() =
            printfn "type2.method2"

    [<Interface>]
    type InterfaceType1 =
        abstract member method1 : int -> int
        abstract member method2 : string -> unit

Lihat juga