Topik ini membahas penggunaan pustaka .NET dari F#, baik pustaka pihak ketiga dari NuGet maupun pustaka bawaan .NET yang dirancang berorientasi objek. Pembahasannya mencakup pemuatan paket dari skrip fsx dan dari proyek, pemanggilan anggota objek gaya .NET dari kode F#, serta penanganan null pada batas interoperabilitas. Setelah topik ini dibaca, penggunaan paket NuGet melalui dua jalur sekaligus konversi null menjadi tipe option dapat dilakukan dengan pola yang aman.
Memuat paket NuGet dari skrip fsx#
Direktif #r "nuget: NamaPaket, versi" memerintahkan dotnet fsi memuat paket NuGet sebelum skrip dieksekusi. F# Interactive menyelesaikan paket dari nuget.org, menyimpannya ke cache lokal, lalu membuatnya tersedia bagi sisa skrip. Versi dipatok langsung pada direktif agar perilaku skrip tidak berubah ketika pustakanya mengeluarkan versi baru. Contoh berikut menggunakan Newtonsoft.Json, pustaka JSON berorientasi objek yang tersedia di NuGet, untuk mengubah record F# menjadi teks JSON dan sebaliknya.
// #r memuat paket NuGet sebelum skrip dieksekusi; versinya dipatok agar tetap stabil
#r "nuget: Newtonsoft.Json, 13.0.3"
open Newtonsoft.Json
type StatistikUjian =
{ MataPelajaran: string
JumlahPeserta: int
RataRata: float }
let statistik =
{ MataPelajaran = "Matematika"
JumlahPeserta = 32
RataRata = 78.5 }
let json = JsonConvert.SerializeObject(statistik)
printfn "JSON : %s" json
let hasil = JsonConvert.DeserializeObject<StatistikUjian>(json)
printfn "Kembali: %s, %d peserta, rata-rata %F" hasil.MataPelajaran hasil.JumlahPeserta hasil.RataRataJSON : {"MataPelajaran":"Matematika","JumlahPeserta":32,"RataRata":78.5}
Kembali: Matematika, 32 peserta, rata-rata 78.500000Fungsi SerializeObject menerima record dan menghasilkan teks JSON dengan nama field sebagai kunci, sedangkan DeserializeObject<StatistikUjian> mengubah teks kembali menjadi record. Keduanya merupakan metode statis pada kelas JsonConvert milik pustaka, dan F# memanggilnya seperti fungsi biasa tanpa sintaks tambahan. Alur skrip tidak memerlukan pendaftaran referensi proyek apa pun, cukup satu baris direktif di bagian atas berkas.
Memuat paket ke dalam proyek#
Proyek yang dibangun dengan dotnet memuat paket melalui elemen PackageReference pada berkas fsproj, dan elemen itu ditambahkan dengan perintah dotnet add package. Perintah dotnet new dan dotnet add package mencetak ringkasan progres yang memuat durasi serta jalur berkas, sehingga keluarannya tidak ditempelkan pada topik ini. Langkahnya adalah membuat proyek, menambahkan paket dengan versi yang dipatok, lalu mengisi kode programnya.
# membuat proyek konsol F# bernama UjiNuget
dotnet new console -lang F# -o UjiNuget
# menambahkan paket NuGet dengan versi yang dipatok
dotnet add UjiNuget package Newtonsoft.Json --version 13.0.3Hasil perintah dotnet add package dapat dilihat langsung pada berkas fsproj, yaitu satu elemen <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> di dalam ItemGroup. Elemen itulah sumber kebenaran tunggal referensi paket pada proyek, sehingga penambahan manual pun sah dilakukan. Setiap eksekusi dotnet run memeriksa elemen tersebut dan memulihkan paket yang belum ada di cache sebelum membangun.
Berkas Program.fs berikut mengisi proyek tersebut, dengan isi yang mengikuti skrip pada bagian sebelumnya.
// tidak-dijalankan: berkas proyek ini dieksekusi melalui blok bash berikutnya
open Newtonsoft.Json
type StatistikUjian =
{ MataPelajaran: string
JumlahPeserta: int
RataRata: float }
let statistik =
{ MataPelajaran = "Matematika"
JumlahPeserta = 32
RataRata = 78.5 }
let json = JsonConvert.SerializeObject(statistik)
printfn "JSON : %s" json
let hasil = JsonConvert.DeserializeObject<StatistikUjian>(json)
printfn "Kembali: %s, %d peserta, rata-rata %F" hasil.MataPelajaran hasil.JumlahPeserta hasil.RataRata# menuliskan isi Program.fs proyek dari berkas yang ditampilkan di atas
cp Program.fs UjiNuget/Program.fs
# menjalankan proyek, paket telah terpasang pada langkah sebelumnya
dotnet run --project UjiNugetJSON : {"MataPelajaran":"Matematika","JumlahPeserta":32,"RataRata":78.5}
Kembali: Matematika, 32 peserta, rata-rata 78.500000Isi Program.fs sama persis dengan skrip pada bagian sebelumnya, kecuali baris #r yang dihapus karena referensi paket kini diurus berkas fsproj. Perintah dotnet run membangun proyek lalu mengeksekusinya, dan hasilnya identik dengan alur skrip. Pendekatan proyek digunakan ketika kode akan diuji, dikemas, atau dibagikan, sedangkan alur fsx cocok untuk eksperimen cepat.
Pustaka bawaan .NET dari sudut pandang F##
Sebagian besar pustaka bawaan .NET dirancang berorientasi objek, dan F# memanggilnya langsung melalui notasi titik tanpa lapisan khusus. Dua contoh yang sering digunakan adalah System.Text.StringBuilder untuk menyusun teks secara bertahap dan System.Collections.Generic.List<'T> untuk daftar yang isinya boleh bertambah dan berkurang. Keduanya dirancang mutable, sehingga penggunaannya di F# memang sengaja dan terbatas pada kebutuhan yang cocok.
// Pustaka bawaan .NET yang berorientasi objek digunakan langsung dari F#
open System
open System.Collections.Generic
open System.Text
// StringBuilder menyusun teks secara bertahap pada satu objek mutable
let susunRingkasan(nilai: int list) =
let papan = StringBuilder()
papan.Append("Rekap nilai: ") |> ignore
papan.Append(String.Join(", ", nilai |> List.map string)) |> ignore
papan.ToString()
printfn "%s" (susunRingkasan([80; 45; 75]))
// List<'T> dari System.Collections.Generic: daftar yang boleh bertambah dan berkurang
let antrean = List<string>()
antrean.Add("Ali")
antrean.Add("Budi")
antrean.Add("Citra")
printfn "Jumlah: %d" antrean.Count
antrean.Remove("Budi") |> ignore
printfn "Sisa : %d" antrean.Count
for nama in antrean do
printfn "Dilayani: %s" namaRekap nilai: 80, 45, 75
Jumlah: 3
Sisa : 2
Dilayani: Ali
Dilayani: CitraMember yang nilai kembaliannya tidak digunakan lebih lanjut disisihkan dengan operator |> ignore, misalnya hasil Append yang mengembalikan papan itu sendiri agar dapat dirantai. Properti Count dibaca tanpa tanda kurung sesuai bentuknya di .NET, sedangkan String.Join memperlihatkan fungsi statis .NET yang dipanggil seperti fungsi F# biasa. Untuk logika domain sehari-hari, koleksi F# seperti list dan Map tetap lebih diutamakan, sedangkan StringBuilder dan List<'T> masuk akal pada batas interoperabilitas atau pada penyusunan teks dan antrean yang memang berubah secara bertahap.
Menangani null di batas#
F# tidak memperkenalkan null pada tipe domainnya, tetapi pustaka .NET tetap mengembalikan null untuk nilai yang tidak ada. Nilai semacam itu sah di dunia .NET dan menjadi sumber error yang paling sering muncul di batas interoperabilitas. Dua perkakas F# menutup celah ini, yaitu fungsi isNull untuk memeriksa keberadaan nilai dan Option.ofObj untuk mengubah nilai yang mungkin null menjadi tipe option.
// #r memuat paket NuGet; JObject membaca dokumen JSON berorientasi objek
#r "nuget: Newtonsoft.Json, 13.0.3"
open Newtonsoft.Json.Linq
let json = """{"Judul":null,"Isi":"Periksa ulang lampiran"}"""
let dokumen = JObject.Parse(json)
// API .NET mengembalikan null untuk field yang kosong
let judul = dokumen.Value<string>("Judul")
printfn "Judul null? %b" (isNull judul)
// Option.ofObj mengubah nilai yang mungkin null menjadi tipe Option
let judulAman = Option.ofObj judul
match judulAman with
| Some teks -> printfn "Judul: %s" teks
| None -> printfn "Judul tidak ada dalam JSON"
let penulis = dokumen.SelectToken("Penulis")
printfn "Penulis null? %b" (isNull penulis)
match Option.ofObj penulis with
| Some token -> printfn "Penulis: %s" (string token)
| None -> printfn "Field Penulis tidak ada"Judul null? true
Judul tidak ada dalam JSON
Penulis null? true
Field Penulis tidak adaPanggilan Value<string>("Judul") mengembalikan null karena field JSON memang bernilai null, sedangkan SelectToken("Penulis") mengembalikan null karena field itu tidak ada sama sekali. Fungsi isNull memeriksa keduanya tanpa risiko error, dan Option.ofObj mengubahnya menjadi Some atau None agar keputusan atas nilai yang tidak ada dituliskan dengan match seperti biasa. Setelah dikonversi, null tidak menyebar lebih jauh ke dalam kode F#.
Ringkasan#
- Direktif
#r "nuget: ..."memuat paket pada skrip fsx, sedangkan proyek memuat paket melaluidotnet add packageyang menulisPackageReferencepada berkas fsproj. - Pustaka bawaan .NET dipanggil dari F# melalui notasi titik, dan nilai kembalian yang sengaja disisihkan diberi
|> ignore. isNullmemeriksa keberadaan nilai dari pustaka .NET, sedangkanOption.ofObjmengubahnya menjadiSomeatauNoneagar null tidak menyebar ke dalam kode F#.
Referensi#
- F# Interactive (dotnet fsi) — Microsoft Learn — Direktif pemuatan paket NuGet dan perilaku F# Interactive.
- dotnet add package — Microsoft Learn — Perintah CLI untuk menambahkan referensi paket pada berkas proyek.
- StringBuilder Class — Microsoft Learn — Kelas penyusun teks mutable pada pustaka bawaan .NET.
- Options — Microsoft Learn — Tipe option beserta konversi dari nilai yang mungkin null.