Namespace layanan (F#)
Namespace layanan memungkinkan Anda mengatur kode ke dalam area fungsionalitas terkait dengan memungkinkan Anda melampirkan nama ke pengelompokan elemen program F#. Namespace layanan biasanya merupakan elemen tingkat atas dalam file F#.
Sintaks
namespace [rec] [parent-namespaces.]identifier
Keterangan
Jika Anda ingin meletakkan kode di namespace layanan, deklarasi pertama dalam file harus mendeklarasikan namespace layanan. Isi dari seluruh file kemudian menjadi bagian dari namespace layanan, asalkan tidak ada deklarasi namespace layanan lain yang ada lebih jauh di dalam file. Jika demikian, semua kode hingga deklarasi namespace layanan berikutnya dianggap berada dalam namespace layanan pertama.
Namespace layanan tidak dapat secara langsung berisi nilai dan fungsi. Sebaliknya, nilai dan fungsi harus disertakan dalam modul, dan modul disertakan dalam namespace layanan. Namespace dapat berisi jenis dan modul.
Komentar dokumen XML dapat dideklarasikan di atas namespace layanan, tetapi diabaikan. Arahan kompilator juga dapat dideklarasikan di atas namespace layanan.
Namespace layanan dapat dideklarasikan secara eksplisit dengan kata kunci namespace layanan, atau secara implisit saat mendeklarasikan sebuah modul. Untuk mendeklarasikan namespace layanan secara eksplisit, gunakan kata kunci namespace layanan diikuti dengan nama namespace layanan. Contoh berikut menunjukkan file kode yang mendeklarasikan namespace layanan Widgets
dengan jenis dan modul yang disertakan dalam namespace layanan tersebut.
namespace Widgets
type MyWidget1 =
member this.WidgetName = "Widget1"
module WidgetsModule =
let widgetName = "Widget2"
Jika seluruh isi file berada dalam satu modul, Anda juga dapat mendeklarasikan namespace layanan secara implisit dengan menggunakan kata kunci module
dan memberikan nama namespace layanan baru dalam nama modul yang sepenuhnya memenuhi syarat. Contoh berikut menunjukkan file kode yang mendeklarasikan namespace layanan Widgets
dan modul WidgetsModule
, yang berisi fungsi.
module Widgets.WidgetModule
let widgetFunction x y =
printfn "%A %A" x y
Kode berikut sama dengan kode sebelumnya, tetapi modulnya adalah deklarasi modul lokal. Dalam hal ini, namespace layanan harus muncul pada barisnya sendiri.
namespace Widgets
module WidgetModule =
let widgetFunction x y =
printfn "%A %A" x y
Jika lebih dari satu modul diperlukan dalam file yang sama dalam satu atau lebih namespace layanan, Anda harus menggunakan deklarasi modul lokal. Saat Anda menggunakan deklarasi modul lokal, Anda tidak dapat menggunakan namespace layanan yang memenuhi syarat dalam deklarasi modul. Kode berikut menunjukkan file yang memiliki deklarasi namespace layanan dan dua deklarasi modul lokal. Dalam hal ini, modul terkandung langsung di namespace layanan; tidak ada modul yang dibuat secara implisit yang memiliki nama yang sama dengan file. Kode lain apa pun dalam file, seperti pengikatan do
, ada di namespace layanan tetapi tidak di modul dalam, jadi Anda harus memenuhi syarat anggota modul widgetFunction
dengan menggunakan nama modul.
namespace Widgets
module WidgetModule1 =
let widgetFunction x y =
printfn "Module1 %A %A" x y
module WidgetModule2 =
let widgetFunction x y =
printfn "Module2 %A %A" x y
module useWidgets =
do
WidgetModule1.widgetFunction 10 20
WidgetModule2.widgetFunction 5 6
Output dari contoh ini adalah sebagai berikut.
Module1 10 20
Module2 5 6
Untuk informasi selengkapnya, lihat Modul.
Namespace Layanan Berlapis
Saat membuat namespace berlapis, Anda harus sepenuhnya memenuhi syarat. Jika tidak, Anda membuat namespace layanan tingkat atas baru. Indentasi diabaikan dalam deklarasi namespace layanan.
Contoh berikut menunjukkan cara mendeklarasikan namespace layanan berlapis.
namespace Outer
// Full name: Outer.MyClass
type MyClass() =
member this.X(x) = x + 1
// Fully qualify any nested namespaces.
namespace Outer.Inner
// Full name: Outer.Inner.MyClass
type MyClass() =
member this.Prop1 = "X"
Namespace Layanan dalam File dan Rakitan
Namespace layanan dapat menjangkau banyak file dalam satu proyek atau kompilasi. Istilah fragmen namespace layanan menjelaskan bagian dari namespace layanan yang disertakan dalam satu file. Namespace layanan juga dapat menjangkau beberapa rakitan. Misalnya, namespace layanan System
mencakup seluruh .NET Framework, yang mencakup banyak rakitan dan berisi banyak namespace layanan berlapis.
Namespace Layanan Global
Anda menggunakan namespace layanan global
yang telah ditentukan sebelumnya untuk menempatkan nama di namespace layanan tingkat atas .NET.
namespace global
type SomeType() =
member this.SomeMember = 0
Anda juga dapat menggunakan global untuk mereferensikan namespace layanan .NET tingkat atas, misalnya, untuk menyelesaikan konflik nama dengan namespace layanan lain.
global.System.Console.WriteLine("Hello World!")
Namespace layanan rekursif
Namespace layanan juga dapat dideklarasikan sebagai rekursif untuk memungkinkan semua kode yang terkandung saling rekursif. Ini dilakukan melalui namespace rec
. Penggunaan namespace rec
dapat mengurangi rasa sakit karena tidak dapat menulis kode referensial timbal balik antara jenis dan modul. Berikut ini adalah contohnya:
namespace rec MutualReferences
type Orientation = Up | Down
type PeelState = Peeled | Unpeeled
// This exception depends on the type below.
exception DontSqueezeTheBananaException of Banana
type Banana(orientation: Orientation) =
member val IsPeeled = false with get, set
member val Orientation = orientation with get, set
member val Sides: PeelState list = [Unpeeled; Unpeeled; Unpeeled; Unpeeled] with get, set
member self.Peel() = BananaHelpers.peel self // Note the dependency on the BananaHelpers module.
member self.SqueezeJuiceOut() = raise (DontSqueezeTheBananaException self) // This member depends on the exception above.
module BananaHelpers =
let peel (banana: Banana) =
let flip (banana: Banana) =
match banana.Orientation with
| Up ->
banana.Orientation <- Down
banana
| Down -> banana
// Update the peel state for all sides of the banana.
let peelSides (banana: Banana) =
banana.Sides
|> List.map (function
| Unpeeled -> Peeled
| Peeled -> Peeled)
// Apply the flipping and peeling logic based on the orientation.
match banana.Orientation with
| Up -> banana |> flip |> peelSides
| Down -> banana |> peelSides
Perhatikan bahwa pengecualian DontSqueezeTheBananaException
dan kelas Banana
keduanya saling merujuk. Selain itu, modul BananaHelpers
dan kelas Banana
juga saling merujuk. Ini tidak mungkin diungkapkan dalam F# jika Anda menghapus kata kunci rec
dari namespace layanan MutualReferences
.
Fitur ini juga tersedia untuk Modul tingkat atas.