Fungsi struct CFML: himpunan lengkap dan cara selamat
Himpunan lengkap fungsi struct CFML di Lucee, dari structNew hingga structReduce dan akses selamat, dengan jadual rujukan serta contoh konfigurasi bersarang.

Kandungan
- Fungsi struct CFML: himpunan lengkap dan cara selamat
- Apa itu struct dalam CFML
- Struct biasa lawan struct berjenis
- Fungsi asas: cipta, isi, kemas kini dan padam
- Fungsi carian dan kewujudan
- Fungsi lelaran: structEach, structReduce dan structMap
- Struct bersarang dan akses selamat
- Salinan cetek lawan salinan dalam
- Susunan kunci dalam JSON dan struct ordered
- Jadual rujukan fungsi struct
- Contoh praktikal: konfigurasi bersarang dengan nilai lalai
- Soalan Lazim (FAQ)
- Sumber
- Senarai semak
Fungsi struct CFML: himpunan lengkap dan cara selamat
Struct ialah bekas pasangan kunci dan nilai, dan ia asas kepada hampir setiap skop CFML. Skop URL, FORM, session, application dan variables semuanya struct. Artikel ini menyenaraikan fungsi struct yang disahkan dalam Lucee 7.1, membeza struct biasa dengan struct berjenis, dan menunjukkan cara membaca struct bersarang dengan selamat.
Apa itu struct dalam CFML
Struct menyimpan nilai di bawah kunci rentetan, bukan kedudukan bernombor seperti array. Anda membaca nilai dengan profil.nama atau profil["nama"]. Kunci mesti unik, dan menetapkan kunci yang sama dua kali menggantikan nilai lama. Untuk senarai berurutan, gunakan array seperti dalam panduan fungsi array CFML.
Jawapan API yang dihurai dengan deserializeJSON hampir selalu struct bersarang, dan skop CFML juga struct, seperti dalam panduan memahami scope dalam CFML.
Struct biasa lawan struct berjenis
structNew() tanpa argumen mencipta struct biasa yang tidak menjamin susunan kunci, dan kunci literal tanpa petik ditukar menjadi huruf besar. Untuk mengekalkan susunan sisipan, hantar jenis sebagai argumen:
// struct biasa: susunan kunci tidak dijamin
biasa = { b: 2, a: 1, c: 3 };
// struct ordered: susunan sisipan dikekalkan
tertib = structNew("ordered");
tertib.b = 2;
tertib.a = 1;
tertib.c = 3;
writeOutput("biasa: " & serializeJSON(biasa) & "<br>");
writeOutput("tertib: " & serializeJSON(tertib) & "<br>");
Jenis yang diterima ialah normal, ordered, linked, soft, weak dan synchronized. ordered dan linked mengekalkan susunan sisipan, dan inilah jenis untuk JSON yang susunan kuncinya penting.
Fungsi asas: cipta, isi, kemas kini dan padam
structInsert menambah kunci, structUpdate menukar nilai kunci sedia ada, dan structDelete membuang kunci, manakala structKeyExists, structCount dan structIsEmpty memeriksa keadaan struct:
// Cipta struct kosong, isi dan kemas kini
profil = structNew();
structInsert(profil, "nama", "Ali");
structInsert(profil, "umur", 30);
structInsert(profil, "aktif", true);
structUpdate(profil, "umur", 31);
writeOutput("nama: " & profil.nama & "<br>");
writeOutput("ada kunci aktif? " & structKeyExists(profil, "aktif") & "<br>");
writeOutput("bilangan kunci: " & structCount(profil) & "<br>");
writeOutput("kosong? " & structIsEmpty(profil) & "<br>");
structDelete(profil, "aktif");
writeOutput("selepas padam: " & structKeyExists(profil, "aktif") & "<br>");
writeOutput("senarai kunci: " & structKeyList(profil) & "<br>");
writeOutput("array kunci: " & serializeJSON(structKeyArray(profil)) & "<br>");
structClear(profil);
writeOutput("kosong selepas clear? " & structIsEmpty(profil) & "<br>");
structKeyList memulangkan kunci sebagai rentetan dipisah koma, structKeyArray memulangkan tatasusunan yang mudah digelung, dan structClear mengosongkan struct tanpa membuang objeknya.
Fungsi carian dan kewujudan
structFind memulangkan nilai satu kunci. Ia menerima nama kunci, bukan laluan bertitik: menghantar "pelanggan.nama" membaling ralat key [pelanggan.nama] doesn't exist kerana enjin mencari kunci literal yang mengandungi titik. Untuk menggerudi bersarang, guna structFindKey dan structFindValue:
data = {
pelanggan: { nama: "Ali", emel: "ali@contoh.my" },
pesanan: { id: 1, jumlah: 99.90 }
};
// structFind pulang nilai satu kunci, bukan laluan bertitik
pel = structFind(data, "pelanggan");
writeOutput("find: " & pel.nama & "<br>");
// structFindKey mencari kunci di seluruh struct bersarang
hasil = structFindKey(data, "emel");
writeOutput("findKey: " & serializeJSON(hasil) & "<br>");
// structFindValue mencari nilai
cari = structFindValue(data, "Ali");
writeOutput("findValue: " & serializeJSON(cari) & "<br>");
Kedua-duanya memulangkan tatasusunan struct dengan medan path dan owner supaya anda tahu lokasi padanan.
Fungsi lelaran: structEach, structReduce dan structMap
structEach menjalankan panggilan balik untuk setiap pasangan, structReduce melipat struct menjadi satu nilai, structMap memulangkan struct baharu, dan gelung for-in mengulang kunci:
stok = { epal: 3, oren: 2, mangga: 5 };
// for-in ke atas kunci struct
for (k in stok) {
writeOutput(k & "=" & stok[k] & ";");
}
writeOutput("<br>");
// structEach dengan fungsi tanpa nama
structEach(stok, function(k, v) {
writeOutput("each:" & k & "=" & v & ";");
});
writeOutput("<br>");
// structReduce menjumlahkan nilai
jumlah = structReduce(stok, function(acc, k, v) {
return acc + v;
}, 0);
writeOutput("jumlah: " & jumlah & "<br>");
// structMap pulang struct baharu
ganda = structMap(stok, function(k, v) {
return v * 2;
});
writeOutput("ganda: " & serializeJSON(ganda) & "<br>");
Panggilan balik structEach dan structMap menerima kunci dahulu kemudian nilai, manakala structReduce menerima penumpuk dahulu. structValueArray memulangkan tatasusunan nilai sahaja.
Struct bersarang dan akses selamat
Membaca pengguna.alamat.bandar meletup dengan key [BANDAR] doesn't exist sekiranya alamat tiada. Tiga bentuk akses selamat mengelakkannya: ?: memberi nilai lalai, ?. berhenti selamat pada rantaian bersarang, dan [ ] menerima kunci dinamik:
pengguna = { nama: "Siti" };
// elvis ?: memberi nilai lalai bila kunci tiada
writeOutput("nama: " & (pengguna.nama ?: "tanpa nama") & "<br>");
writeOutput("emel: " & (pengguna.emel ?: "tiada emel") & "<br>");
// safe navigation ?. untuk struct bersarang yang mungkin tiada
writeOutput("bandar: " & (pengguna.alamat?.bandar ?: "tiada") & "<br>");
// akses kurungan selamat dengan kunci dinamik
kunci = "emel";
writeOutput("emel dinamik: " & (pengguna[kunci] ?: "tiada") & "<br>");
Ketiga-tiganya terbina dalam CFML, jadi ia berfungsi tanpa pustaka tambahan, berguna semasa menghurai JSON luar yang bentuknya tidak tetap.
Salinan cetek lawan salinan dalam
structCopy membuat salinan cetek, jadi struct bersarang masih dikongsi dengan asal. duplicate membuat salinan dalam yang bebas sepenuhnya:
asal = { nama: "Ali", alamat: { bandar: "Kuala Lumpur" } };
// structCopy: salinan cetek, struct bersarang dikongsi
cetek = structCopy(asal);
cetek.alamat.bandar = "Johor Bahru";
writeOutput("asal selepas ubah cetek: " & asal.alamat.bandar & "<br>");
// duplicate: salinan dalam, struct bersarang bebas
dalam = duplicate(asal);
dalam.alamat.bandar = "Pulau Pinang";
writeOutput("asal selepas ubah dalam: " & asal.alamat.bandar & "<br>");
writeOutput("dalam: " & dalam.alamat.bandar & "<br>");
Salinan cetek ialah punca pepijat senyap. Guna duplicate apabila anda memerlukan kebebasan penuh.
Susunan kunci dalam JSON dan struct ordered
Struct biasa tidak menjanjikan susunan kunci, dan ini ketara dalam JSON. Dalam ujian pada Lucee 7.1, struct dengan kunci b, a, c diserikan sebagai A, B, C, susunan abjad dan bukan susunan asal. Struct ordered mengekalkan susunan sisipan. Ini penting untuk integrasi yang memerlukan susunan medan tetap, seperti dibincangkan dalam artikel serializeJSON dan deserializeJSON. Peraturannya mudah: kalau susunan kunci JSON penting, guna structNew("ordered").
Jadual rujukan fungsi struct
Jadual ini ialah rujukan pantas bagi fungsi yang disahkan berjalan dalam Lucee 7.1.
| Fungsi | Tujuan | Nota |
|---|---|---|
| structNew([jenis]) | Cipta struct baharu | jenis: normal, ordered, linked, soft, weak, synchronized |
| structInsert(s, k, v) | Sisip kunci dan nilai | argumen keempat boleh halang tulis ganti |
| structUpdate(s, k, v) | Kemas kini nilai kunci sedia ada | |
| structDelete(s, k) | Padam kunci | |
| structKeyExists(s, k) | Semak kewujudan kunci | |
| structFind(s, k) | Pulang nilai satu kunci | bukan laluan bertitik |
| structFindKey(s, k) | Cari kunci dalam struct bersarang | pulang tatasusunan path dan owner |
| structFindValue(s, v) | Cari nilai dalam struct bersarang | pulang tatasusunan path dan owner |
| structKeyList(s) | Rentetan kunci dipisah koma | |
| structKeyArray(s) | Tatasusunan kunci | |
| structCount(s) | Bilangan kunci | |
| structIsEmpty(s) | Benar jika kosong | |
| structClear(s) | Kosongkan semua kunci | |
| structCopy(s) | Salinan cetek | struct bersarang dikongsi |
| duplicate(s) | Salinan dalam | setiap peringkat bebas |
| structEach(s, cb) | Lelar pasangan kunci dan nilai | |
| structReduce(s, cb, init) | Kurangkan kepada satu nilai | penumpuk dahulu dalam panggilan balik |
| structMap(s, cb) | Petakan kepada struct baharu | |
| structValueArray(s) | Tatasusunan nilai |
Contoh praktikal: konfigurasi bersarang dengan nilai lalai
Contoh berikut menggabungkan semuanya: membaca konfigurasi bersarang dengan nilai lalai bagi kunci yang mungkin tiada, contohnya tetapan baharu pada pelayan lama:
// Konfigurasi bersarang biasa dalam aplikasi
konfig = {
pangkalan: { host: "localhost", port: 3306 },
cache: { didayakan: true, ttl: 300 }
};
// Baca laluan bertitik dengan nilai lalai yang selamat
function bacaTetapan(required struct konfig, required string laluan, lalai) {
var bahagian = listToArray(laluan, ".");
var semasa = konfig;
for (var b in bahagian) {
if (!structKeyExists(semasa, b)) {
return lalai;
}
semasa = semasa[b];
}
return semasa;
}
writeOutput("host: " & bacaTetapan(konfig, "pangkalan.host", "127.0.0.1") & "<br>");
writeOutput("port: " & bacaTetapan(konfig, "pangkalan.port", 5432) & "<br>");
writeOutput("ttl: " & bacaTetapan(konfig, "cache.ttl", 60) & "<br>");
writeOutput("log: " & bacaTetapan(konfig, "log.tahap", "info") & "<br>");
bacaTetapan menelusuri laluan bertitik satu peringkat pada satu masa dan memulangkan nilai lalai sebaik sahaja kunci tiada, jadi ia tidak meletup pada konfigurasi yang tidak lengkap. Konfigurasi aplikasi biasanya ditetapkan dalam Application.cfc.
Soalan Lazim (FAQ)
Apakah perbezaan antara struct dan array dalam CFML?
Struct menyimpan nilai di bawah kunci rentetan tanpa susunan terjamin, manakala array menyimpan nilai mengikut kedudukan bernombor. Guna struct untuk data berbentuk tetap dan array untuk senarai berurutan.
Bila saya patut guna struct ordered dan bukannya struct biasa?
Guna structNew("ordered") apabila susunan kunci penting, contohnya semasa menyerikan ke JSON untuk sistem luar yang memerlukan susunan medan tetap.
Adakah kunci struct sensitif huruf besar atau kecil?
Ya. Kunci literal tanpa petik ditukar menjadi huruf besar, jadi { umur: 30 } mencipta kunci UMUR. Guna petik seperti { "umur": 30 } untuk mengekalkan huruf kecil.
Apakah perbezaan structCopy dan duplicate?
structCopy membuat salinan cetek, jadi struct bersarang dikongsi dengan asal. duplicate membuat salinan dalam yang bebas sepenuhnya.
Bagaimana saya membaca nilai bersarang dengan selamat tanpa ralat?
Gunakan ?. untuk rantaian bersarang dan ?: untuk nilai lalai, contohnya pengguna.alamat?.bandar ?: "tiada".
Sumber
- StructNew pada dokumentasi Lucee
- StructFind pada dokumentasi Lucee
- StructEach pada dokumentasi Lucee
- Ben Nadel, Exploring Linked Ordered Structs in Lucee 5.3
Senarai semak
- Fahami bahawa skop CFML ialah struct, jadi kemahiran struct ialah kemahiran harian.
- Guna
structNew("ordered")apabila susunan kunci dalam JSON penting. - Jangan hantar laluan bertitik kepada
structFind, gunastructFindKeyuntuk bersarang. - Guna
?.,?:dan akses kurungan untuk membaca bersarang tanpa ralat. - Guna
duplicatedan bukannyastructCopyapabila anda memerlukan salinan bebas.